001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package com.tctest;
006:
007: import com.tc.cluster.Cluster;
008: import com.tc.config.schema.setup.L1TVSConfigurationSetupManager;
009: import com.tc.lang.TCThreadGroup;
010: import com.tc.lang.ThrowableHandler;
011: import com.tc.logging.TCLogging;
012: import com.tc.management.JMXConnectorProxy;
013: import com.tc.management.beans.L2MBeanNames;
014: import com.tc.object.BaseDSOTestCase;
015: import com.tc.object.DistributedObjectClient;
016: import com.tc.object.PauseListener;
017: import com.tc.object.bytecode.MockClassProvider;
018: import com.tc.object.bytecode.NullManager;
019: import com.tc.object.bytecode.hook.impl.PreparedComponentsFromL2Connection;
020: import com.tc.object.config.DSOClientConfigHelper;
021: import com.tc.object.config.StandardDSOClientConfigHelperImpl;
022: import com.tc.objectserver.control.ServerControl;
023: import com.tc.stats.DSOMBean;
024: import com.tc.test.proxyconnect.ProxyConnectManager;
025: import com.tc.test.proxyconnect.ProxyConnectManagerImpl;
026: import com.tc.test.restart.RestartTestEnvironment;
027: import com.tc.test.restart.RestartTestHelper;
028: import com.tc.util.PortChooser;
029:
030: import java.util.ArrayList;
031: import java.util.List;
032:
033: import javax.management.MBeanServerConnection;
034: import javax.management.MBeanServerInvocationHandler;
035: import javax.management.remote.JMXConnector;
036:
037: public class DeadClientCrashedServerReconnectTest extends
038: BaseDSOTestCase {
039:
040: private TestPauseListener pauseListener;
041:
042: public DeadClientCrashedServerReconnectTest() {
043: // this.disableAllUntil("3001-01-01");
044: }
045:
046: public void setUp() {
047: pauseListener = new TestPauseListener();
048: }
049:
050: public void testClientsStayDeadAcrossRestarts() throws Exception {
051: final boolean isCrashy = true; // so persistence will be on
052: PortChooser portChooser = new PortChooser();
053: List jvmArgs = new ArrayList();
054: int proxyPort = portChooser.chooseRandomPort();
055:
056: RestartTestHelper helper = new RestartTestHelper(isCrashy,
057: new RestartTestEnvironment(this .getTempDirectory(),
058: portChooser, RestartTestEnvironment.DEV_MODE),
059: jvmArgs);
060: int dsoPort = helper.getServerPort();
061: int jmxPort = helper.getAdminPort();
062: ServerControl server = helper.getServerControl();
063:
064: ProxyConnectManager mgr = new ProxyConnectManagerImpl();
065: mgr.setDsoPort(dsoPort);
066: mgr.setProxyPort(proxyPort);
067: mgr.setupProxy();
068:
069: server.start();
070:
071: mgr.proxyUp();
072:
073: // config for client
074: configFactory().addServerToL1Config(null, proxyPort, jmxPort);
075: L1TVSConfigurationSetupManager manager = super
076: .createL1ConfigManager();
077:
078: DSOClientConfigHelper configHelper = new StandardDSOClientConfigHelperImpl(
079: manager);
080: PreparedComponentsFromL2Connection components = new PreparedComponentsFromL2Connection(
081: manager);
082: DistributedObjectClient client = new DistributedObjectClient(
083: configHelper,
084: new TCThreadGroup(new ThrowableHandler(TCLogging
085: .getLogger(DistributedObjectClient.class))),
086: new MockClassProvider(), components, NullManager
087: .getInstance(), new Cluster());
088: client.setPauseListener(pauseListener);
089: client.start();
090:
091: // wait until client handshake is complete...
092: pauseListener.waitUntilUnpaused();
093:
094: checkServerHasClients(1, jmxPort);
095:
096: Thread.sleep(5 * 1000);
097:
098: // disconnect the client from the server... this should make the server kill the client from the server
099: // perspective...
100: mgr.proxyDown();
101:
102: // give time for server to process client disconnect
103: Thread.sleep(5 * 1000);
104:
105: // Now crash the server
106: server.crash();
107:
108: // start the server back up
109: server.start();
110: mgr.proxyUp();
111:
112: // give time for jmx server to start up
113: Thread.sleep(15 * 1000);
114:
115: assertTrue(pauseListener.isPaused());
116:
117: checkServerHasClients(0, jmxPort);
118: }
119:
120: private void checkServerHasClients(int clientCount, int jmxPort)
121: throws Exception {
122: JMXConnector jmxConnector = new JMXConnectorProxy("localhost",
123: jmxPort);
124: MBeanServerConnection mbs = jmxConnector
125: .getMBeanServerConnection();
126: DSOMBean mbean = (DSOMBean) MBeanServerInvocationHandler
127: .newProxyInstance(mbs, L2MBeanNames.DSO,
128: DSOMBean.class, true);
129: int actualClientCount = mbean.getClients().length;
130: if (actualClientCount != clientCount) {
131: throw new AssertionError(
132: "Incorrect number of clients connected to the server: expected=["
133: + clientCount + "] but was actual=["
134: + actualClientCount + "].");
135: }
136:
137: System.out.println("***** " + clientCount
138: + " clients are connected to the server.");
139: jmxConnector.close();
140: }
141:
142: private static final class TestPauseListener implements
143: PauseListener {
144:
145: private boolean paused = true;
146:
147: public void waitUntilPaused() throws InterruptedException {
148: waitUntilCondition(true);
149: }
150:
151: public void waitUntilUnpaused() throws InterruptedException {
152: waitUntilCondition(false);
153: }
154:
155: public boolean isPaused() {
156: synchronized (this ) {
157: return paused;
158: }
159: }
160:
161: private void waitUntilCondition(boolean b)
162: throws InterruptedException {
163: synchronized (this ) {
164: while (b != paused) {
165: wait();
166: }
167: }
168: }
169:
170: public void notifyPause() {
171: synchronized (this ) {
172: paused = true;
173: notifyAll();
174: }
175: }
176:
177: public void notifyUnpause() {
178: synchronized (this ) {
179: paused = false;
180: notifyAll();
181: }
182: }
183:
184: }
185:
186: }
|