TopologyViewTest.java revision 0d397efc4b781ef5b60108708fa1131467d2c3c8
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at
* trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
* add the following below this CDDL HEADER, with the fields enclosed
* by brackets "[]" replaced with your own identifying information:
* Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
*
* Copyright 2008-2009 Sun Microsystems, Inc.
*/
/**
* Some tests to know if at any time the view DSs and RSs have of the current
* topology is accurate, even after some connections, disconnections and
* re-connections events.
*/
public class TopologyViewTest extends ReplicationTestCase
{
// Server id definitions
private static final int DS1_ID = 1;
private static final int DS2_ID = 2;
private static final int DS3_ID = 3;
private static final int DS4_ID = 4;
private static final int DS5_ID = 5;
private static final int DS6_ID = 6;
private static final int RS1_ID = 51;
private static final int RS2_ID = 52;
private static final int RS3_ID = 53;
// Group id definitions
private static final int DS1_GID = 1;
private static final int DS2_GID = 1;
private static final int DS3_GID = 2;
private static final int DS4_GID = 2;
private static final int DS5_GID = 3;
private static final int DS6_GID = 3;
private static final int RS1_GID = 1;
private static final int RS2_GID = 2;
private static final int RS3_GID = 3;
// Assured conf definitions
private static final int DS1_SDL = -1;
private static final int DS2_SDL = -1;
private static final int DS3_SDL = 1;
private static final int DS4_SDL = -1;
private static final int DS5_SDL = 2;
private static final int DS6_SDL = -1;
static
{
}
private int rs1Port = -1;
private int rs2Port = -1;
private int rs3Port = -1;
// The tracer object for the debug logger
{
if (debugEnabled())
{
}
}
private void initTest()
{
rs1Port = -1;
rs2Port = -1;
rs3Port = -1;
}
private void endTest()
{
{
}
{
}
{
}
{
}
{
}
{
}
try
{
// Clear any reference to a domain in synchro plugin
} catch (DirectoryException ex)
{
}
{
}
{
}
{
}
rs1Port = -1;
rs2Port = -1;
rs3Port = -1;
}
{
try
{
} catch (InterruptedException ex)
{
}
}
/**
* Check connection of the provided replication domain to the provided
* replication server. Waits for connection to be ok up to secTimeout seconds
* before failing.
*/
{
int rsPort = -1;
switch (dsId)
{
case DS1_ID:
break;
case DS2_ID:
break;
case DS3_ID:
break;
case DS4_ID:
break;
case DS5_ID:
break;
case DS6_ID:
break;
default:
fail("Unknown replication domain server id.");
}
switch (rsId)
{
case RS1_ID:
break;
case RS2_ID:
break;
case RS3_ID:
break;
default:
fail("Unknown replication server id.");
}
int nSec = 0;
// Go out of the loop only if connection is verified or if timeout occurs
while (true)
{
// Test connection
int rdPort = -1;
boolean rightPort = false;
if (connected)
{
try
{
} catch (Exception e)
{
}
rightPort = true;
}
{
// Connection verified
+ nSec + " seconds.");
return;
}
// Sleep 1 second
try
{
} catch (InterruptedException ex)
{
}
nSec++;
if (nSec > secTimeout)
{
// Timeout reached, end with error
}
}
}
/**
* Find needed free TCP ports.
*/
private void findFreePorts()
{
try
{
} catch (IOException e)
{
fail("Unable to determinate some free ports " +
}
}
/**
* Creates the list of servers to represent the RS topology excluding the
* RS whose id is passed.
*/
{
if (rsIdToExclude != RS1_ID)
{
}
if (rsIdToExclude != RS2_ID)
{
}
if (rsIdToExclude != RS3_ID)
{
}
return replServers;
}
/**
* Creates a new ReplicationServer.
*/
{
try
{
int rsPort = -1;
int groupId = -1;
switch (rsId)
{
case RS1_ID:
break;
case RS2_ID:
break;
case RS3_ID:
break;
default:
fail("Unknown replication server id.");
}
return replicationServer;
} catch (Exception e)
{
}
return null;
}
/**
* Creates and starts a new ReplicationDomain with the correct list of
* know RSs according to DS id
*/
{
try
{
int groupId = -1;
int assuredSdLevel = -100;
// Fill rs list according to defined scenario (see testTopologyChanges
// comment)
switch (dsId)
{
case DS1_ID:
break;
case DS2_ID:
break;
case DS3_ID:
break;
case DS4_ID:
break;
case DS5_ID:
break;
case DS6_ID:
break;
default:
fail("Unknown replication domain server id.");
}
return replicationDomain;
} catch (Exception e)
{
}
return null;
}
// Definitions of steps for the test case
private static final int STEP_1 = 1;
private static final int STEP_2 = 2;
private static final int STEP_3 = 3;
private static final int STEP_4 = 4;
private static final int STEP_5 = 5;
private static final int STEP_6 = 6;
private static final int STEP_7 = 7;
private static final int STEP_8 = 8;
private static final int STEP_9 = 9;
private static final int STEP_10 = 10;
private static final int STEP_11 = 11;
private static final int STEP_12 = 12;
private static final int STEP_13 = 13;
/**
* Perform connections/disconnections of DS/RS. Uses various config parameters
* that are embedded in topo info to check if they are well transported.
* This tests:
* - if topo msgs are exchanged when needed and reflect topo reality (who is
* connected to who)
* - if topo msgs transport config params in terms of assured replication,
* group id... that reflect what is configured in the DSs.
*
* Full topo is:
* (GID=group id, A=assured, NA=not assured, SR=safe read, SD=safe data,
* SDL=safe data level, RUF=ref urls filled, RUE=ref urls empty)
* Except if otherwise stated, RSs and DSs are aware of every others existence
* - RS1 with GID=1
* - RS2 with GID=2
* - RS3 with GID=3
* - DS1 with GID=1, NA
* - DS2 with GID=1, A, SR, RUF
* - DS3 with GID=2, A, SD, SDL=1 (DS3 does not know RS1 and RS3)
* - DS4 with GID=2, A, SR, RUE (DS4 does not know RS1 and RS3)
* - DS5 with GID=3, A, SD, SDL=2 (DS5 does not know RS1)
* - DS6 with GID=3, A, SR, RUF (DS6 does not know RS1)
* Scenario is:
* - RS1 starts
* - DS1 starts and connects to RS1 (check topo view in DS1)
* - DS2 starts and connects to RS1 (check topo view in DS1,DS2)
* - RS2 starts (check topo view in DS1,DS2)
* - DS3 starts and connects to RS2 (check topo view in DS1,DS2,DS3)
* - DS4 starts and connects to RS2 (check topo view in DS1,DS2,DS3,DS4)
* - DS5 starts and connects to RS2 (check topo view in DS1,DS2,DS3,DS4,DS5)
* - RS3 starts (check topo view in DS1,DS2,DS3,DS4,DS5)
* - DS6 starts and connects to RS3. DS5 should reconnect to RS3 (as RS with
* same GID becomes available) (check topo view in DS1,DS2,DS3,DS4,DS5,DS6)
* - DS6 stops (check topo view in DS1,DS2,DS3,DS4,DS5)
* - DS6 starts and connects to RS3 (check topo view in DS1,DS2,DS3,DS4,DS5,
* DS6)
* - RS3 stops. DS5 and DS6 should failover to RS2 as do not know RS1 (check
* topo view in DS1,DS2,DS3,DS4,DS5,DS6)
* - RS3 starts. DS5 and DS6 should reconnect to RS3 (as RS with same GID
* becomes available) (check topo view in DS1,DS2,DS3,DS4,DS5,DS6)
* - RS2 stops. DS3 and DS4 do not reconnect to any RS as do not know RS1 and
* RS3. This emulates a full RS with his connected DSs crash. (check topo view
* in DS1,DS2,DS5,DS6)
* @throws Exception If a problem occurred
*/
public void testTopologyChanges() throws Exception
{
initTest();
try
{
/**
* RS1 starts
*/
debugInfo("*** STEP 0 ***");
/**
* DS1 starts and connects to RS1 (check topo view in DS1)
*/
debugInfo("*** STEP 1 ***");
/**
* DS2 starts and connects to RS1 (check topo view in DS1,DS2)
*/
debugInfo("*** STEP 2 ***");
/**
* RS2 starts (check topo view in DS1,DS2)
*/
debugInfo("*** STEP 3 ***");
/**
* DS3 starts and connects to RS2 (check topo view in DS1,DS2,DS3)
*/
debugInfo("*** STEP 4 ***");
/**
* DS4 starts and connects to RS2 (check topo view in DS1,DS2,DS3,DS4)
*/
debugInfo("*** STEP 5 ***");
/**
* DS5 starts and connects to RS2 (check topo view in DS1,DS2,DS3,DS4,DS5)
*/
debugInfo("*** STEP 6 ***");
/**
* RS3 starts. DS5 should reconnect to RS3 (as RS with
* same GID becomes available) (check topo view in DS1,DS2,DS3,DS4,DS5)
*/
debugInfo("*** STEP 7 ***");
/**
* DS6 starts and connects to RS3 (check topo view in DS1,DS2,DS3,DS4,DS5,
* DS6)
*/
debugInfo("*** STEP 8 ***");
/**
* DS6 stops (check topo view in DS1,DS2,DS3,DS4,DS5)
*/
debugInfo("*** STEP 9 ***");
/**
* DS6 starts and connects to RS3 (check topo view in DS1,DS2,DS3,DS4,DS5,
* DS6)
*/
debugInfo("*** STEP 10 ***");
/**
* RS3 stops. DS5 and DS6 should failover to RS2 as do not know RS1 (check
* topo view in DS1,DS2,DS3,DS4,DS5,DS6)
*/
debugInfo("*** STEP 11 ***");
/**
* RS3 starts. DS5 and DS6 should reconnect to RS3 (as RS with same GID
* becomes available) (check topo view in DS1,DS2,DS3,DS4,DS5,DS6)
*/
debugInfo("*** STEP 12 ***");
/**
* RS2 stops. DS3 and DS4 do not reconnect to any RS as do not know RS1 and
* RS3. This emulates a full RS with his connected DSs crash. (check topo
* view in DS1,DS2,DS5,DS6)
*/
debugInfo("*** STEP 13 ***");
} finally
{
endTest();
}
}
/**
* Creates RSInfo for the passed RS
*/
{
int groupId = -1;
switch (rsId)
{
case RS1_ID:
break;
case RS2_ID:
break;
case RS3_ID:
break;
default:
fail("Unknown replication server id.");
}
}
/**
* Creates DSInfo for the passed DS, connected to the passed RS
*/
{
byte groupId = -1;
int assuredSdLevel = -100;
switch (dsId)
{
case DS1_ID:
break;
case DS2_ID:
break;
case DS3_ID:
break;
case DS4_ID:
break;
case DS5_ID:
break;
case DS6_ID:
break;
default:
fail("Unknown replication domain server id.");
}
// Perform necessary conversions
{
}
}
/**
* Creates the topo view to be checked at each step of the test (view that
* every concerned DS should have)
*/
{
switch (step)
{
case STEP_1:
break;
case STEP_2:
break;
case STEP_3:
break;
case STEP_4:
break;
case STEP_5:
break;
case STEP_6:
break;
case STEP_7:
break;
case STEP_8:
break;
case STEP_9:
break;
case STEP_10:
break;
case STEP_11:
break;
case STEP_12:
break;
case STEP_13:
break;
default:
}
}
/**
* Get the topo view each DS in the provided ds list has and compares it
* with the theoretical topology view that every body should have at the time
* this method is called.
*/
{
for(int currentDsId : dsIdList)
{
switch (currentDsId)
{
case DS1_ID:
break;
case DS2_ID:
break;
case DS3_ID:
break;
case DS4_ID:
break;
case DS5_ID:
break;
case DS6_ID:
break;
default:
fail("Unknown replication domain server id.");
}
/**
* Get the topo view of the current analyzed DS
*/
// Add info for DS itself:
// we need to clone the list as we don't want to modify the list kept
// inside the DS.
{
}
DSInfo dsInfo = new DSInfo(dsId, rsId, TEST_DN_WITH_ROOT_ENTRY_GENID, status, assuredFlag, assuredMode,
/**
* Compare to what is the expected view
*/
}
}
/**
* Bag class representing a view of the topology at a given time
* (who is connected to who, what are the config parameters...)
*/
private class TopoView
{
{
}
{
// Check dsList
return false;
{
int found = 0;
{
found++;
}
// Not found
if (found == 0)
return false;
// Should never see twice as dsInfo structure in a dsList
// Ok, found exactly once in the list, examine next structure
}
// Check rsList
return false;
{
int found = 0;
{
found++;
}
// Not found
if (found == 0)
return false;
// Should never see twice as rsInfo structure in a dsList
// Ok, found exactly once in the list, examine next structure
}
return true;
}
{
{
}
{
}
return ("TopoView:" +
"CONNECTED RS SERVERS:\n" + rsStr);
}
}
}