3853N/A * The contents of this file are subject to the terms of the 3853N/A * Common Development and Distribution License, Version 1.0 only 3853N/A * (the "License"). You may not use this file except in compliance 3853N/A * You can obtain a copy of the license at 3853N/A * See the License for the specific language governing permissions 3853N/A * and limitations under the License. 3853N/A * When distributing Covered Code, include this CDDL HEADER in each 3853N/A * file and include the License file at 3853N/A * add the following below this CDDL HEADER, with the fields enclosed 3853N/A * by brackets "[]" replaced with your own identifying information: 3853N/A * Portions Copyright [yyyy] [name of copyright owner] 5086N/A * Copyright 2009-2010 Sun Microsystems, Inc. 5414N/A * Portions Copyright 2011 ForgeRock AS 3853N/A * Some tests to go through the DS state machine and validate we get the 3853N/A * expected status according to the actions we perform. 3853N/A // The tracer object for the debug logger 3853N/A // Clear any reference to a domain in synchro plugin 3853N/A * Check connection of the provided ds to the 3853N/A * replication server. Waits for connection to be ok up to secTimeout seconds 3853N/A // Go out of the loop only if connection is verified or if timeout occurs 3853N/A " to RS obtained after " +
nSec +
" seconds.");
3853N/A // Timeout reached, end with error 3853N/A fail(
"checkConnection: DS " +
dsId +
" is not connected to the RS after " 3853N/A * Find needed free TCP ports. 3853N/A fail(
"Unable to determinate some free ports " +
3853N/A * Creates a new ReplicationServer. 3853N/A * Creates and starts a new ReplicationDomain configured for the replication 3853N/A * Create and connect a replication broker to the replication server with 3853N/A * the given state and generation id (uses passed window for received changes) 3853N/A * Create and connect a replication broker to the replication server with 3853N/A * the given state and generation id (uses 100 as window for received changes) 3853N/A * Make simple state machine test. 3853N/A * NC = Not connected status 3853N/A * BG = Bad generation id status 3853N/A * @throws Exception If a problem occurred 3853N/A * DS1 start, no RS available: DS1 should be in not connected status 3853N/A * RS1 starts , DS1 should connect to it and be in normal status 3853N/A * RS1 stops, DS1 should go in not connected status 3853N/A // Returns various init values for test testStateMachineStatusAnalyzer 3853N/A * Test the status analyzer system that allows to go from normal to degraded 3853N/A * and vice versa, using the configured threshold value 3853N/A * NC = Not connected status 3853N/A * BG = Bad generation id status 3853N/A * @throws Exception If a problem occurred 3853N/A * RS1 starts with specified threshold value 3853N/A * DS2 starts and connects to RS1. No reader and low window value at the 3853N/A * beginning so writer for DS2 in RS should enqueue changes after first 3853N/A * changes sent to DS. (window value reached: a window msg needed by RS for 3853N/A * following sending changes to DS) 3853N/A * DS3 starts and connects to RS1 3853N/A // Send first changes to reach window and block DS2 writer queue. Writer will take them 3853N/A // from queue and block (no more changes removed from writer queue) after 3853N/A // having sent them to TCP receive queue of DS2. 3853N/A * DS3 sends changes (less than threshold): DS2 should still be in normal 3853N/A * status so no topo message should be sent (update topo message 3853N/A * for telling status of DS2 changed) 3988N/A sleep(
1000);
// Be sure status analyzer has time to test 3853N/A * DS3 sends changes to reach the threshold value, DS3 should receive an 3853N/A * update topo message with status of DS2: degraded status 3988N/A // wait for a status MSG status analyzer to broker 3 3988N/A sleep(
200);
// Be sure status analyzer has time to test 3853N/A * DS3 sends 10 additional changes after threshold value, DS2 should still be 3853N/A * degraded so no topo message received. 3988N/A sleep(
1000);
// Be sure status analyzer has time to test 3853N/A * DS2 replays every changes and should go back to normal status 3853N/A * (create a reader to emulate replay of messages (messages read from queue)) 3988N/A // wait for a status MSG status analyzer to broker 3 3988N/A sleep(
200);
// Be sure status analyzer has time to test 3853N/A * Go through the possible state machine transitions: 3853N/A * NC = Not connected status 3853N/A * BG = Bad generation id status 3853N/A * ->NC->D->N->NC->N->D->NC->D->N->BG->NC->N->D->BG->FU->NC->N->D->FU->NC->BG->NC->N->FU->NC->N->NC 3853N/A * @throws Exception If a problem occurred 3853N/A * RS1 starts with 1 message as degraded status threshold value 3853N/A * DS2 starts and connects to RS1 3853N/A * DS2 starts sending a lot of changes 3853N/A sleep(
1000);
// Let some messages being queued in RS 3853N/A * DS1 starts and connects to RS1, server state exchange should lead to 3853N/A * start in degraded status as some changes should be in queued in the RS 3853N/A * and the threshold value is 1 change in queue. 3853N/A * DS2 stops sending changes: DS1 should replay pending changes and should 3853N/A // Sleep enough so that replay can be done and analyzer has time 3853N/A // to see that the queue length is now under the threshold value. 3853N/A * RS1 stops to make DS1 go to not connected status (from normal status) 3853N/A * DS2 restarts with up to date server state (this allows to have 3853N/A * restarting RS1 not sending him some updates he already sent) 3853N/A * RS1 restarts, DS1 should get back to normal status 3853N/A * DS2 sends again a lot of changes to make DS1 degraded again 3853N/A sleep(
8000);
// Let some messages being queued in RS, and analyzer see the change 3853N/A * RS1 stops to make DS1 go to not connected status (from degraded status) 3853N/A * DS2 restarts with up to date server state (this allows to have 3853N/A * restarting RS1 not sending him some updates he already sent) 3853N/A * RS1 restarts, DS1 should reconnect in degraded status (from not connected 3853N/A * this time, not from state machine entry) 3853N/A // It is too difficult to tune the right sleep so disabling this test: 3853N/A // Sometimes the status analyzer may be fast and quickly change the status 3853N/A //sleepAssertStatusEquals(30, ds1, ServerStatus.DEGRADED_STATUS); 3853N/A * DS1 should come back in normal status after a while 3853N/A * DS2 sends a reset gen id order with wrong gen id: DS1 should go into bad generation id status 3853N/A * DS2 sends again a reset gen id order with right id: DS1 should be disconnected 3853N/A * by RS then reconnect and enter again in normal status. This goes through 3853N/A * not connected status but not possible to check as should reconnect immediately 3853N/A br.
shutdown();
// Reader could reconnect broker, but gen id would be bad: need to recreate a broker to send changex 3853N/A * DS2 sends again a lot of changes to make DS1 degraded again 3853N/A sleep(
8000);
// Let some messages being queued in RS, and analyzer see the change 3853N/A * DS2 sends reset gen id order with bad gen id: DS1 should go in bad gen id 3853N/A * status (from degraded status this time) 3988N/A resetGenId(
ds2, -
1);
// -1 to allow next step full update and flush RS db so that DS1 can reconnect after full update 3853N/A * DS2 engages full update (while DS1 in bad gen id status), DS1 should go 3853N/A * DS2 terminates full update to DS1: DS1 should reconnect (goes through not connected status) 3853N/A * and come back to normal status (RS genid was -1 so RS will adopt ne genb id) 3853N/A * DS2 sends changes to DS1: DS1 should go in degraded status 3853N/A ds2.
stop();
// will need a new broker with another gen id restart it 3853N/A sleep(
8000);
// Let some messages being queued in RS, and analyzer see the change 3853N/A * DS2 engages full update (while DS1 in degraded status), DS1 should go 3853N/A * DS2 terminates full update to DS1: DS1 should reconnect (goes through not connected status) 3853N/A * and come back to bad gen id status (RS genid was another gen id (300 entries instead of 200)) 3853N/A * DS2 sends reset gen id with gen id same as DS1: DS1 will be disconnected 3853N/A * by RS (not connected status) and come back to normal status 3853N/A ds2.
stop();
// will need a new broker with another gen id restart it 3853N/A * DS2 engages full update (while DS1 in normal status), DS1 should go 3853N/A * DS2 terminates full update to DS1: DS1 should reconnect (goes through not connected status) 3853N/A * and come back to normal status (process full update with same data as 3853N/A * before so RS already has right gen id: version with 300 entries) 3853N/A * RS1 stops, DS1 should go to not connected status 3853N/A * If the environment could not be set up. 3853N/A // Note: this test does not use the memory test backend as for having a DS 3853N/A // going into degraded status, we need to send a lot of updates. This makes 3853N/A // the memory test backend crash with OutOfMemoryError. So we prefer here 3853N/A // a backend backed up with a file 3853N/A * Clean up the environment. 3853N/A * @throws Exception If the environment could not be set up. 3853N/A * Sends a reset genid message through the given replication broker, with the 3853N/A * Utility class for making a full update through a broker. No separated thread 3853N/A * BrokerInitializer bi = new BrokerInitializer(rb, sid, nEntries); 3853N/A * bi.initFullUpdate(); // Initializes a full update session by sending InitializeTargetMsg 3853N/A * bi.runFullUpdate(); // loops sending nEntries entries and finalizes the full update by sending the EntryDoneMsg 4802N/A private int destId = -
1;
// Server id of server to initialize 3853N/A * If the BrokerInitializer is to be used for a lot of entries to send 3853N/A * (which is often the case), the reader thread should be enabled to make 3853N/A * the window subsystem work and allow the broker to send as much entries as 3853N/A * he wants. If not enabled, the user is responsible to call the receive 3853N/A * method of the broker himself. 3853N/A * Creates a broker initializer with a reader 3853N/A * Creates a broker initializer. Also creates a reader according to request 3853N/A * Initializes a full update session by sending InitializeTargetMsg 3853N/A // Send init msg to warn dest server it is going do be initialized 3853N/A // Send top entry for the domain 3853N/A +
"entryUUID: 11111111-1111-1111-1111-111111111111\n\n";
3853N/A "objectClass: person\n" +
"objectClass: organizationalPerson\n" +
3853N/A "objectClass: inetOrgPerson\n" +
3853N/A "homePhone: 951-245-7634\n" +
3853N/A "description: This is the description for Aaccf Amar.\n" +
"st: NC\n" +
3853N/A "postalAddress: Aaccf Amar$17984 Thirteenth Street" +
3853N/A "$Rockford, NC 85762\n" +
"mail: user.1@example.com\n" +
3853N/A "cn: Aaccf Amar\n" +
"l: Rockford\n" +
"pager: 508-763-4246\n" +
3853N/A "street: 17984 Thirteenth Street\n" +
"telephoneNumber: 216-564-6748\n" +
3853N/A "employeeNumber: 1\n" +
"sn: Amar\n" +
"givenName: Aaccf\n" +
3853N/A "postalCode: 85762\n" +
"userPassword: password\n" +
"initials: AA\n" +
3853N/A // -> WARNING: EntryMsg PDUs are concatenated before calling import on LDIF 3853N/A // file so need \n\n to separate LDIF entries to conform to LDIF file format 3853N/A * Loops sending entries for full update (EntryMsg messages). When 3853N/A * terminates, sends the EntryDoneMsg to finalize full update. Number of 3853N/A * sent entries is determined at initFullUpdate call time. 3853N/A * Thread for sending a lot of changes through a broker. 3853N/A // The writer starts suspended 3853N/A // Tells a sending session is finished 3853N/A // A session is sending messages between the follow and the pause calls, 3853N/A // or the time a followAndPause method runs. 3853N/A * If the BrokerWriter is to be used for a lot of changes to send (which is 3853N/A * often the case), the reader thread should be enabled to make the window 3853N/A * subsystem work and allow the broker to send as much changes as he wants. 3853N/A * If not enabled, the user is responsible to call the receive method of 3853N/A /* Creates a broker writer with a reader */ 3853N/A /* Creates a broker writer. Also creates a reader according to request */ 3853N/A // Create a Change number generator to generate new change numbers 3853N/A // when we need to send changes 3853N/A // Start thread (is paused by default so will have to call follow anyway) 3853N/A * Loops sending changes: add operations creating users with different ids 3853N/A * This starts paused and has to be resumed calling a follow method. 3853N/A // No stop msg when entering the loop (thread starts with paused writer) 3853N/A // When not in pause, loop sending changes to RS 3853N/A // End session if amount of changes sent has been requested 3853N/A // Requested number of changes to send sent, end session 3853N/A // Mark session is finished 3853N/A // Writer in pause, sleep a while to let other threads work 3853N/A * Suspends the writer thread 3853N/A return;
// Already suspended 3853N/A // Wait for all messages sent 3853N/A * Test if the writer is suspended 3853N/A * Resumes the writer thread until it is paused 3853N/A * Resumes the writer and suspends it after a given amount of ms 3853N/A * If the writer was working it will be paused anyway after the given amount 3853N/A * Resumes the writer and suspends it after a given amount of changes has been 3853N/A * sent. If the writer was working it will be paused anyway after the given 3853N/A * amount of changes, starting from the current call time. 3853N/A // Initialize counter system variables 3853N/A // Wait for all messages sent 3853N/A "objectClass: person\n" +
"objectClass: organizationalPerson\n" +
3853N/A "objectClass: inetOrgPerson\n" +
3853N/A "homePhone: 951-245-7634\n" +
3853N/A "description: This is the description for Aaccf Amar.\n" +
"st: NC\n" +
3853N/A "postalAddress: Aaccf Amar$17984 Thirteenth Street" +
3853N/A "$Rockford, NC 85762\n" +
"mail: user.1@example.com\n" +
3853N/A "cn: Aaccf Amar\n" +
"l: Rockford\n" +
"pager: 508-763-4246\n" +
3853N/A "street: 17984 Thirteenth Street\n" +
"telephoneNumber: 216-564-6748\n" +
3853N/A "employeeNumber: 1\n" +
"sn: Amar\n" +
"givenName: Aaccf\n" +
3853N/A "postalCode: 85762\n" +
"userPassword: password\n" +
"initials: AA\n" +
3853N/A // Create an update message to add an entry. 3853N/A * This simple reader just throws away the received 3853N/A * messages. It is used on a breaker we want to be able to send or read from some message 3853N/A * with (changes, entries (full update)...). Calling the receive method of the 3853N/A * broker allows to unblock the window mechanism and to send the desired messages. 3853N/A * Calling the updateWindowAfterReplay method allows to send when necessary the 3853N/A * window message to the RS to allow him send other messages he may want to send us. 3853N/A // Loop reading and throwing update messages 3853N/A // Returns last received message from reader 3853N/A // When read, last value is cleared 3853N/A * Waits for a long time for an equality condition to be true. 3853N/A * Every second, the equality check is performed. After the provided amount of 3853N/A * seconds, if the equality is false, an assertion error is raised. 3853N/A * This methods ends either because the equality is true or if the timeout 3853N/A * occurs after the provided number of seconds. 3853N/A * This method is convenient when the the equality can only occur after a 3853N/A * period of time which is difficult to establish, but we know it will occur 3853N/A * anyway. This has 2 advantages compared to a classical code like this: 3853N/A * - assertEquals(testedValue, expectedValue); 3853N/A * 1. If the sleep value is too big, this will impact the total time of 3853N/A * running tests uselessly. It may also penalize a fast running machine where 3853N/A * the sleep time value may be unnecessarily to long. 3853N/A * 2. If the sleep value is too small, some slow machines may have the test 3853N/A * fail whereas some additional time would have made the test succeed. 3853N/A * @param secTimeout Number of seconds to wait before failing. The value for 3853N/A * this should be high. A timeout is needed anyway to have the test campaign 3853N/A * @param testedValue The value we want to test 3853N/A * @param expectedValue The value the tested value should be equal to 3853N/A fail(
"sleepAssertStatusEquals: null parameters");
3853N/A // Go out of the loop only if equality is obtained or if timeout occurs 3853N/A // Timeout reached, end with error