1
2/*
3 */
4
5package com.sleepycat.db.test;
6
7import org.junit.Before;
8import org.junit.BeforeClass;
9import org.junit.After;
10import org.junit.AfterClass;
11import org.junit.Test;
12import static org.junit.Assert.assertEquals;
13import static org.junit.Assert.fail;
14import junit.framework.JUnit4TestAdapter;
15
16import java.io.File;
17import java.io.FileNotFoundException;
18import java.util.Vector;
19
20import com.sleepycat.db.*;
21
22public class RepmgrElectionTest extends EventHandlerAdapter implements Runnable
23{
24    static String address = "localhost";
25    static int    basePort = 4242;
26    static String baseDirName = "";
27    File homedir;
28    EnvironmentConfig envConfig;
29    Environment dbenv;
30
31    @BeforeClass public static void ClassInit() {
32	    TestUtils.loadConfig(null);
33	    baseDirName = TestUtils.BASETEST_DBDIR + "/TESTDIR";
34    }
35
36    @AfterClass public static void ClassShutdown() {
37    }
38
39    @Before public void PerTestInit()
40        throws Exception {
41    }
42
43    @After public void PerTestShutdown()
44        throws Exception {
45        for(int j = 0; j < NUM_WORKER_THREADS; j++)
46        {
47            String homedirName = baseDirName+j;
48            TestUtils.removeDir(homedirName);
49        }
50    }
51
52    private static boolean lastSiteStarted = false;
53    private static int NUM_WORKER_THREADS = 5;
54    @Test(timeout=180000) public void startConductor()
55    {
56        Vector<RepmgrElectionTest> workers = new Vector<RepmgrElectionTest>(NUM_WORKER_THREADS);
57        // start the worker threads
58        for (int i = 0; i < NUM_WORKER_THREADS; i++) {
59            RepmgrElectionTest worker = new RepmgrElectionTest(i);
60            worker.run();
61            workers.add(worker);
62            /*
63            while (!lastSiteStarted) {
64            try {
65            java.lang.Thread.sleep(10);
66            }catch(InterruptedException e){}
67            }
68            lastSiteStarted = false;
69            */
70        }
71
72        // stop the master - ensure the client with the highest priority is elected.
73
74        // re-start original master. Call election ensure correct client is elected
75    }
76
77    /*
78     * Worker thread implementation
79     */
80    private final static int priorities[] = {100, 75, 50, 50, 25};
81    private int threadNumber;
82    public RepmgrElectionTest() {
83        // needed to comply with JUnit, since there is also another constructor.
84    }
85    RepmgrElectionTest(int threadNumber) {
86        this.threadNumber = threadNumber;
87    }
88
89    public void run() {
90        EnvironmentConfig envConfig;
91        Environment dbenv = null;
92        TestUtils.DEBUGOUT(1, "Creating worker: " + threadNumber);
93        try {
94            File homedir = new File(baseDirName + threadNumber);
95
96            if (homedir.exists()) {
97                // The following will fail if the directory contains sub-dirs.
98                if (homedir.isDirectory()) {
99                    File[] contents = homedir.listFiles();
100                    for (int i = 0; i < contents.length; i++)
101                        contents[i].delete();
102                }
103                homedir.delete();
104            }
105            homedir.mkdir();
106        } catch (Exception e) {
107            TestUtils.DEBUGOUT(2, "Warning: initialization had a problem creating a clean directory.\n"+e);
108        }
109        try {
110            homedir = new File(baseDirName+threadNumber);
111        } catch (NullPointerException npe) {
112            // can't really happen :)
113        }
114        envConfig = new EnvironmentConfig();
115        envConfig.setErrorStream(TestUtils.getErrorStream());
116        envConfig.setErrorPrefix("RepmgrElectionTest test("+threadNumber+")");
117        envConfig.setAllowCreate(true);
118        envConfig.setRunRecovery(true);
119        envConfig.setThreaded(true);
120        envConfig.setInitializeLocking(true);
121        envConfig.setInitializeLogging(true);
122        envConfig.setInitializeCache(true);
123        envConfig.setTransactional(true);
124        envConfig.setTxnNoSync(true);
125        envConfig.setInitializeReplication(true);
126        envConfig.setVerboseReplication(false);
127
128        ReplicationHostAddress haddr = new ReplicationHostAddress(address, basePort+threadNumber);
129        envConfig.setReplicationManagerLocalSite(haddr);
130        envConfig.setReplicationPriority(priorities[threadNumber]);
131        envConfig.setEventHandler(this);
132        envConfig.setReplicationManagerAckPolicy(ReplicationManagerAckPolicy.ALL);
133
134
135        try {
136            dbenv = new Environment(homedir, envConfig);
137
138        } catch(FileNotFoundException e) {
139            fail("Unexpected FNFE in standard environment creation." + e);
140        } catch(DatabaseException dbe) {
141            fail("Unexpected database exception came from environment create." + dbe);
142        }
143
144        try {
145            /*
146             * If all threads are started with REP_ELECTION flag
147             * The whole system freezes, and I get:
148             * RepmgrElectionTest test(0): Waiting for handle count (1) or msg_th (0) to complete replication lockout
149             * Repeated every minute.
150             */
151	    envConfig = dbenv.getConfig();
152	    for(int existingSites = 0; existingSites < threadNumber; existingSites++)
153	    {
154		/*
155                 * This causes warnings to be produced - it seems only
156                 * able to make a connection to the master site, not other
157                 * client sites.
158                 * The documentation and code lead me to believe this is not
159                 * as expected - so leaving in here for now.
160                 */
161                ReplicationHostAddress host = new ReplicationHostAddress(
162		    address, basePort+existingSites);
163                envConfig.replicationManagerAddRemoteSite(host, false);
164	    }
165	    dbenv.setConfig(envConfig);
166	    if(threadNumber == 0)
167                dbenv.replicationManagerStart(NUM_WORKER_THREADS, ReplicationManagerStartPolicy.REP_MASTER);
168            else
169                dbenv.replicationManagerStart(NUM_WORKER_THREADS, ReplicationManagerStartPolicy.REP_CLIENT);
170        } catch(DatabaseException dbe) {
171            fail("Unexpected database exception came from replicationManagerStart." + dbe);
172        }
173        TestUtils.DEBUGOUT(1, "Started replication site: " + threadNumber);
174        lastSiteStarted = true;
175        try {
176            java.lang.Thread.sleep(10000);
177        }catch(InterruptedException ie) {}
178        try {
179            dbenv.close();
180            Environment.remove(homedir, false, envConfig);
181        } catch(FileNotFoundException fnfe) {
182        } catch(DatabaseException dbe) {
183            fail("Unexpected database exception came during shutdown." + dbe);
184        }
185    }
186
187    /*
188     * End worker thread implementation
189     */
190    public void handleRepMasterEvent() {
191        TestUtils.DEBUGOUT(1, "Got a REP_MASTER message");
192        TestUtils.DEBUGOUT(1, "My priority: " + priorities[threadNumber]);
193    }
194
195    public void handleRepClientEvent() {
196        TestUtils.DEBUGOUT(1, "Got a REP_CLIENT message");
197    }
198
199    public void handleRepNewMasterEvent() {
200        TestUtils.DEBUGOUT(1, "Got a REP_NEW_MASTER message");
201        TestUtils.DEBUGOUT(1, "My priority: " + priorities[threadNumber]);
202    }
203}
204