1
2/*
3 * A test case that brings up the replication
4 * manager infrastructure as master. Then shut
5 * the master down cleanly.
6 * This case does not have any replication clients
7 * or even update the underlying DB.
8 */
9
10package com.sleepycat.db.test;
11
12import org.junit.Before;
13import org.junit.BeforeClass;
14import org.junit.After;
15import org.junit.AfterClass;
16import org.junit.Ignore;
17import org.junit.Test;
18import static org.junit.Assert.assertTrue;
19import static org.junit.Assert.fail;
20import junit.framework.JUnit4TestAdapter;
21
22import java.io.File;
23import java.io.FileNotFoundException;
24
25import com.sleepycat.db.*;
26
27public class RepmgrConfigTest extends EventHandlerAdapter
28{
29    private class ConfigOptions {
30        public ConfigOptions(
31            boolean txnSync,
32            boolean initializeReplication,
33            boolean verboseReplication,
34            boolean setLocalSiteEnable,
35            boolean setReplicationPriority,
36            int replicationPriority,
37            boolean setValidEventHandler,
38            boolean setAckPolicy,
39            ReplicationManagerAckPolicy ackPolicyToSet,
40            int nsitesToStart,
41            boolean validStartPolicy,
42	    int requestMin,
43	    int requestMax,
44            boolean validPolicy
45            )
46        {
47            this.txnSync                 = txnSync;
48            this.initializeReplication   = initializeReplication;
49            this.verboseReplication      = verboseReplication;
50            this.setLocalSiteEnable      = setLocalSiteEnable;
51            this.setReplicationPriority  = setReplicationPriority;
52            this.replicationPriority     = replicationPriority;
53            this.setValidEventHandler    = setValidEventHandler;
54            this.setAckPolicy            = setAckPolicy;
55            this.ackPolicyToSet          = ackPolicyToSet;
56            this.nsitesToStart           = nsitesToStart;
57            this.validStartPolicy        = validStartPolicy;
58            this.validPolicy             = validPolicy;
59	    this.requestMin              = requestMin;
60	    this.requestMax              = requestMax;
61	}
62
63        boolean txnSync;
64        boolean initializeReplication;
65        boolean verboseReplication;
66        boolean setLocalSiteEnable;
67        boolean setValidEventHandler;
68        boolean setReplicationPriority;
69        int replicationPriority;
70        boolean setAckPolicy;
71        ReplicationManagerAckPolicy ackPolicyToSet;
72        int nsitesToStart;
73        boolean validStartPolicy;
74	int requestMin;
75        int requestMax;
76
77        // should this set of options work or not?
78        boolean validPolicy;
79    }
80    static String address     = "localhost";
81    static int    port        = 4242;
82    static int    priority    = 100;
83    static String homedirName = "";
84
85    ConfigOptions[] optionVariations =
86        { new ConfigOptions(true,  true,  false, true,  true,  50, true,  true,  ReplicationManagerAckPolicy.ALL,       1, true, 3, 9, true ), //0:
87          new ConfigOptions(false, true,  false, true,  true,  50, true,  true,  ReplicationManagerAckPolicy.ALL,       1, true, 3, 9, true ), //1: disable txnSync
88          new ConfigOptions(true,  false, false, true,  true,  50, true,  true,  ReplicationManagerAckPolicy.ALL,       1, true, 3, 9, false ), //2: don't call initRep
89          new ConfigOptions(true,  true,  true,  true,  true,  50, true,  true,  ReplicationManagerAckPolicy.ALL,       1, true, 3, 9, true ), //3: enable verbose rep
90          new ConfigOptions(true,  true,  false, false, true,  50, true,  true,  ReplicationManagerAckPolicy.ALL,       1, true, 3, 9, false ), //4: don't set a local site
91          new ConfigOptions(true,  true,  false, true,  false, 50, true,  true,  ReplicationManagerAckPolicy.ALL,       1, true, 3, 9, true ), //5: don't assign priority explicitly
92          new ConfigOptions(true,  true,  false, true,  true,  -1, true,  true,  ReplicationManagerAckPolicy.ALL,       1, true, 3, 9, true ), //6: ??assign an invalid priority.
93          new ConfigOptions(true,  true,  false, true,  true,  50, false, true,  ReplicationManagerAckPolicy.ALL,       1, true, 3, 9, false ), //7: don't set the event handler.
94          new ConfigOptions(true,  true,  false, true,  true,  50, true,  false, ReplicationManagerAckPolicy.ALL,       1, true, 3, 9, true ), //8: ?? don't set ack policy
95          new ConfigOptions(true,  true,  false, true,  true,  50, true,  true,  ReplicationManagerAckPolicy.ALL_PEERS, 1, true, 3, 9, true ), //9:
96          new ConfigOptions(true,  true,  false, true,  true,  50, true,  true,  ReplicationManagerAckPolicy.NONE,      1, true, 3, 9, true ), //10:
97          new ConfigOptions(true,  true,  false, true,  true,  50, true,  true,  ReplicationManagerAckPolicy.ONE,       1, true, 3, 9, true ), //11:
98          new ConfigOptions(true,  true,  false, true,  true,  50, true,  true,  ReplicationManagerAckPolicy.ONE_PEER,  1, true, 3, 9, true ), //12:
99          new ConfigOptions(true,  true,  false, true,  true,  50, true,  true,  null,                                  1, true, 3, 9, false ), //13: set an invalid ack policy
100          new ConfigOptions(true,  true,  false, true,  true,  50, true,  true,  ReplicationManagerAckPolicy.ALL,      -1, true, 3, 9, false ), //14: set nsites negative
101          new ConfigOptions(true,  true,  false, true,  true,  50, true,  true,  ReplicationManagerAckPolicy.ALL,       0, true, 3, 9, false ), //15:
102          new ConfigOptions(true,  true,  false, true,  true,  50, true,  true,  ReplicationManagerAckPolicy.ALL,       1, false, 3, 9, false ), //16: dont set a valid start policy.
103          new ConfigOptions(true,  true,  false, true,  true,  50, true,  true,  ReplicationManagerAckPolicy.ALL,       1, true, 0, 9, false ), //17: set requestMin as 0
104          new ConfigOptions(true,  true,  false, true,  true,  50, true,  true,  ReplicationManagerAckPolicy.ALL,       1, true, 9, 3, false ), //18: set requestMax < requestMin
105        };
106    File homedir;
107    EnvironmentConfig envConfig;
108
109    @BeforeClass public static void ClassInit() {
110	    TestUtils.loadConfig(null);
111	    homedirName = TestUtils.BASETEST_DBDIR + "/TESTDIR";
112    }
113
114    @AfterClass public static void ClassShutdown() {
115    }
116
117    @Before public void PerTestInit()
118    {
119        TestUtils.removeDir(homedirName);
120        try {
121            homedir = new File(homedirName);
122            homedir.mkdir();
123        } catch (Exception e) {
124            TestUtils.DEBUGOUT(2, "Warning: initialization had a problem creating a clean directory.\n" + e);
125        }
126        try {
127            homedir = new File(homedirName);
128        } catch (NullPointerException npe) {
129            // can't really happen :)
130        }
131        envConfig = new EnvironmentConfig();
132        envConfig.setErrorStream(TestUtils.getErrorStream());
133        envConfig.setErrorPrefix("RepmgrConfigTest test");
134        envConfig.setAllowCreate(true);
135        envConfig.setRunRecovery(true);
136        envConfig.setThreaded(true);
137        envConfig.setInitializeLocking(true);
138        envConfig.setInitializeLogging(true);
139        envConfig.setInitializeCache(true);
140        envConfig.setTransactional(true);
141
142        // Linux seems to have problems cleaning up its sockets.
143		// so start each test at a new address.
144		++port;
145    }
146
147    @After public void PerTestShutdown()
148        throws Exception {
149        TestUtils.removeDir(homedirName);
150    }
151
152    @Test (timeout=3000) public void TestOptions0()
153    {
154        assertTrue(runTestWithOptions(optionVariations[0]));
155    }
156    @Test (timeout=3000) public void TestOptions1()
157    {
158        assertTrue(runTestWithOptions(optionVariations[1]));
159    }
160    @Test (timeout=3000) public void TestOptions2()
161    {
162        assertTrue(runTestWithOptions(optionVariations[2]));
163    }
164    @Test (timeout=3000) public void TestOptions3()
165    {
166        assertTrue(runTestWithOptions(optionVariations[3]));
167    }
168    @Test (timeout=3000) public void TestOptions4()
169    {
170        assertTrue(runTestWithOptions(optionVariations[4]));
171    }
172    @Test (timeout=3000) public void TestOptions5()
173    {
174        assertTrue(runTestWithOptions(optionVariations[5]));
175    }
176    @Test (timeout=3000) public void TestOptions6()
177    {
178        assertTrue(runTestWithOptions(optionVariations[6]));
179    }
180    @Ignore("Currently failing") @Test (timeout=3000) public void TestOptions7()
181    {
182        assertTrue(runTestWithOptions(optionVariations[7]));
183    }
184    @Test (timeout=3000) public void TestOptions8()
185    {
186        assertTrue(runTestWithOptions(optionVariations[8]));
187    }
188    @Test (timeout=3000) public void TestOptions9()
189    {
190        assertTrue(runTestWithOptions(optionVariations[9]));
191    }
192    @Test (timeout=3000) public void TestOptions10()
193    {
194        assertTrue(runTestWithOptions(optionVariations[10]));
195    }
196    @Test (timeout=3000) public void TestOptions11()
197    {
198        assertTrue(runTestWithOptions(optionVariations[11]));
199    }
200    @Test (timeout=3000) public void TestOptions12()
201    {
202        assertTrue(runTestWithOptions(optionVariations[12]));
203    }
204    @Test (timeout=3000) public void TestOptions13()
205    {
206        assertTrue(runTestWithOptions(optionVariations[13]));
207    }
208    @Test (timeout=3000) public void TestOptions14()
209    {
210        assertTrue(runTestWithOptions(optionVariations[14]));
211    }
212    @Test (timeout=3000) public void TestOptions15()
213    {
214        assertTrue(runTestWithOptions(optionVariations[15]));
215    }
216    @Test (timeout=3000) public void TestOptions16()
217    {
218        assertTrue(runTestWithOptions(optionVariations[16]));
219    }
220    @Test (timeout=3000) public void TestOptions17()
221    {
222        assertTrue(runTestWithOptions(optionVariations[17]));
223    }
224    @Test (timeout=3000) public void TestOptions18()
225    {
226        assertTrue(runTestWithOptions(optionVariations[18]));
227    }
228
229    // returns true if failure matches options failure spec.
230    boolean runTestWithOptions(ConfigOptions opts)
231    {
232        boolean retval = true;
233        boolean gotexcept = false;
234        Environment dbenv = null;
235        try {
236
237            envConfig.setTxnNoSync(opts.txnSync);
238            if (opts.initializeReplication)
239                envConfig.setInitializeReplication(true);
240            if (opts.verboseReplication)
241                envConfig.setVerboseReplication(false);
242
243            if (opts.setLocalSiteEnable) {
244                ReplicationHostAddress haddr = new ReplicationHostAddress(address, port);
245                envConfig.setReplicationManagerLocalSite(haddr);
246            }
247            if (opts.setReplicationPriority)
248                envConfig.setReplicationPriority(opts.replicationPriority);
249            if (opts.setValidEventHandler)
250                envConfig.setEventHandler(this);
251
252            if (opts.setAckPolicy)
253                envConfig.setReplicationManagerAckPolicy(opts.ackPolicyToSet);
254
255	    envConfig.setReplicationRequestMin(opts.requestMin);
256	    envConfig.setReplicationRequestMax(opts.requestMax);
257
258            try {
259                dbenv = new Environment(homedir, envConfig);
260            } catch(FileNotFoundException e) {
261                TestUtils.DEBUGOUT(3, "Unexpected FNFE in standard environment creation." + e);
262                gotexcept = true;
263                retval = false; // never expect a FNFE
264            } catch(DatabaseException dbe) {
265                    gotexcept = true;
266                if (opts.validPolicy)
267                    TestUtils.DEBUGOUT(3, "Unexpected DB exception from Environment create." + dbe);
268	    } catch(IllegalArgumentException iae){
269	    	    gotexcept = true;
270	       if (opts.validPolicy)
271		    TestUtils.DEBUGOUT(3, "Unexpected DB exception from setRepRequest." + iae);
272	    }
273
274            if (!gotexcept) {
275                try {
276                    // start replication manager
277                    if (opts.validStartPolicy)
278                        dbenv.replicationManagerStart(opts.nsitesToStart, ReplicationManagerStartPolicy.REP_MASTER);
279                    else
280                        dbenv.replicationManagerStart(opts.nsitesToStart, null);
281                } catch(DatabaseException dbe) {
282                        gotexcept = true;
283                    if (opts.validPolicy)
284                        TestUtils.DEBUGOUT(3, "Unexpected database exception came from replicationManagerStart." + dbe);
285                } catch (IllegalArgumentException iae) {
286                        gotexcept = true;
287                    if (opts.validPolicy)
288                        TestUtils.DEBUGOUT(3, "Unexpected IllegalArgumentException came from replicationManagerStart." + iae);
289                } catch (NullPointerException npe) {
290                        gotexcept = true;
291                    if (opts.validPolicy)
292                        TestUtils.DEBUGOUT(3, "Unexpected NullPointerException came from replicationManagerStart." + npe);
293                } catch (AssertionError ae) {
294                        gotexcept = true;
295                    if (opts.validPolicy)
296                        TestUtils.DEBUGOUT(3, "Unexpected AssertionError came from replicationManagerStart." + ae);
297                }
298
299            }
300        } catch (IllegalArgumentException iae) {
301                gotexcept = true;
302	    if (opts.validPolicy)
303                TestUtils.DEBUGOUT(3, "Unexpected IllegalArgumentException." + iae);
304        } catch (AssertionError ae) {
305                gotexcept = true;
306            if (opts.validPolicy)
307                TestUtils.DEBUGOUT(3, "Unexpected AssertionError." + ae);
308        } catch (NullPointerException npe) {
309                gotexcept = true;
310            if (opts.validPolicy)
311                TestUtils.DEBUGOUT(3, "Unexpected NullPointerException." + npe);
312        }
313        if (dbenv != null) {
314            try {
315                java.lang.Thread.sleep(1000);
316            }catch(InterruptedException ie) {}
317            try {
318                dbenv.close();
319                Environment.remove(homedir, true, envConfig);
320            } catch(FileNotFoundException fnfe) {
321                gotexcept = true;
322                retval = false;
323            } catch(DatabaseException dbe) {
324                TestUtils.DEBUGOUT(3, "Unexpected database exception came during shutdown." + dbe);
325                gotexcept = true; // never expect a shutdown failure.
326            }
327        }
328        if (retval) {
329            if (gotexcept == opts.validPolicy)
330                retval = false;
331        }
332        return retval;
333    }
334
335    /*
336     * TODO: Maybe move this into a general TestEventHandler?
337     */
338    public void handleRepMasterEvent() {
339        TestUtils.DEBUGOUT(1, "Got a REP_MASTER message");
340    }
341
342    public void handleRepClientEvent() {
343        TestUtils.DEBUGOUT(1, "Got a REP_CLIENT message");
344    }
345
346    public void handleRepNewMasterEvent() {
347        TestUtils.DEBUGOUT(1, "Got a REP_NEW_MASTER message");
348    }
349}
350