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 org.apache.commons.io.CopyUtils;
008:
009: import com.tc.config.schema.SettableConfigItem;
010: import com.tc.config.schema.setup.TVSConfigurationSetupManagerFactory;
011: import com.tc.config.schema.setup.TestTVSConfigurationSetupManagerFactory;
012: import com.tc.config.schema.test.TerracottaConfigBuilder;
013: import com.tc.management.beans.L2DumperMBean;
014: import com.tc.management.beans.L2MBeanNames;
015: import com.tc.net.proxy.TCPProxy;
016: import com.tc.object.BaseDSOTestCase;
017: import com.tc.object.config.DSOClientConfigHelper;
018: import com.tc.objectserver.control.ExtraProcessServerControl;
019: import com.tc.objectserver.control.ServerControl;
020: import com.tc.properties.TCPropertiesImpl;
021: import com.tc.simulator.app.ApplicationConfigBuilder;
022: import com.tc.simulator.app.ErrorContext;
023: import com.tc.test.ProcessInfo;
024: import com.tc.test.TestConfigObject;
025: import com.tc.test.activepassive.ActivePassiveServerConfigCreator;
026: import com.tc.test.activepassive.ActivePassiveServerManager;
027: import com.tc.test.activepassive.ActivePassiveTestSetupManager;
028: import com.tc.test.proxyconnect.ProxyConnectManager;
029: import com.tc.test.proxyconnect.ProxyConnectManagerImpl;
030: import com.tc.test.restart.RestartTestEnvironment;
031: import com.tc.test.restart.RestartTestHelper;
032: import com.tc.test.restart.ServerCrasher;
033: import com.tc.util.Assert;
034: import com.tc.util.PortChooser;
035: import com.tc.util.runtime.ThreadDump;
036: import com.tctest.runner.DistributedTestRunner;
037: import com.tctest.runner.DistributedTestRunnerConfig;
038: import com.tctest.runner.TestGlobalIdGenerator;
039: import com.tctest.runner.TransparentAppConfig;
040:
041: import java.io.File;
042: import java.io.FileOutputStream;
043: import java.net.InetAddress;
044: import java.net.URL;
045: import java.util.ArrayList;
046: import java.util.Collection;
047: import java.util.HashMap;
048: import java.util.Iterator;
049: import java.util.List;
050: import java.util.Map;
051:
052: import javax.management.MBeanServerConnection;
053: import javax.management.MBeanServerInvocationHandler;
054: import javax.management.remote.JMXConnector;
055:
056: import junit.framework.AssertionFailedError;
057:
058: public abstract class TransparentTestBase extends BaseDSOTestCase
059: implements TransparentTestIface, TestConfigurator {
060:
061: public static final int DEFAULT_CLIENT_COUNT = 2;
062: public static final int DEFAULT_INTENSITY = 10;
063: public static final int DEFAULT_VALIDATOR_COUNT = 0;
064: public static final int DEFAULT_ADAPTED_MUTATOR_COUNT = 0;
065: public static final int DEFAULT_ADAPTED_VALIDATOR_COUNT = 0;
066:
067: private TestTVSConfigurationSetupManagerFactory configFactory;
068: private DSOClientConfigHelper configHelper;
069: protected DistributedTestRunner runner;
070: private DistributedTestRunnerConfig runnerConfig = new DistributedTestRunnerConfig(
071: getTimeoutValueInSeconds());
072: private TransparentAppConfig transparentAppConfig;
073: private ApplicationConfigBuilder possibleApplicationConfigBuilder;
074:
075: private String mode;
076: private ServerControl serverControl;
077: private boolean controlledCrashMode = false;
078: private ServerCrasher crasher;
079: private File javaHome;
080: private int pid = -1;
081: private final ProxyConnectManager proxyMgr = new ProxyConnectManagerImpl();
082:
083: // for active-passive tests
084: private ActivePassiveServerManager apServerManager;
085: private ActivePassiveTestSetupManager apSetupManager;
086: private TestState crashTestState;
087:
088: // used by ResolveTwoActiveServersTest only
089: private ServerControl[] serverControls = null;
090: private TCPProxy[] proxies = null;
091:
092: protected TestConfigObject getTestConfigObject() {
093: return TestConfigObject.getInstance();
094: }
095:
096: protected void setJavaHome() {
097: if (javaHome == null) {
098: String javaHome_local = getTestConfigObject()
099: .getL2StartupJavaHome();
100: if (javaHome_local == null) {
101: throw new IllegalStateException(
102: TestConfigObject.L2_STARTUP_JAVA_HOME
103: + " must be set to a valid JAVA_HOME");
104: }
105: javaHome = new File(javaHome_local);
106: }
107: }
108:
109: protected void setJvmArgsL1Reconnect(ArrayList jvmArgs) {
110: System.setProperty("com.tc.l1.reconnect.enabled", "true");
111: TCPropertiesImpl.setProperty("l1.reconnect.enabled", "true");
112:
113: jvmArgs.add("-Dcom.tc.l1.reconnect.enabled=true");
114: }
115:
116: protected void setUp() throws Exception {
117: setUp(configFactory(), configHelper());
118:
119: // config should be set up before tc-config for external L2s are written out
120: setupConfig(configFactory());
121:
122: if (!canSkipL1ReconnectCheck() && canRunProxyConnect()
123: && !enableL1Reconnect()) {
124: //
125: throw new AssertionError(
126: "proxy-connect needs l1reconnect enabled, please overwrite enableL1Reconnect()");
127: }
128:
129: ArrayList jvmArgs = new ArrayList();
130: addTestTcPropertiesFile(jvmArgs);
131:
132: // for some test cases to enable l1reconnect
133: if (enableL1Reconnect()) {
134: setJvmArgsL1Reconnect(jvmArgs);
135: }
136:
137: RestartTestHelper helper = null;
138: PortChooser portChooser = new PortChooser();
139: if ((isCrashy() && canRunCrash()) || useExternalProcess()) {
140: // javaHome is set here only to enforce that java home is defined in the test config
141: // javaHome is set again inside RestartTestEnvironment because how that class is used
142: // TODO: clean this up
143: setJavaHome();
144:
145: helper = new RestartTestHelper(mode().equals(
146: TestConfigObject.TRANSPARENT_TESTS_MODE_CRASH),
147: new RestartTestEnvironment(getTempDirectory(),
148: portChooser,
149: RestartTestEnvironment.PROD_MODE,
150: configFactory()), jvmArgs);
151: int dsoPort = helper.getServerPort();
152: int adminPort = helper.getAdminPort();
153: ((SettableConfigItem) configFactory().l2DSOConfig()
154: .listenPort()).setValue(dsoPort);
155: ((SettableConfigItem) configFactory().l2CommonConfig()
156: .jmxPort()).setValue(adminPort);
157: if (!canRunProxyConnect())
158: configFactory().addServerToL1Config(null, dsoPort,
159: adminPort);
160: serverControl = helper.getServerControl();
161: } else if (isActivePassive() && canRunActivePassive()) {
162: setUpActivePassiveServers(portChooser, jvmArgs);
163: } else {
164: int dsoPort = portChooser.chooseRandomPort();
165: int adminPort = portChooser.chooseRandomPort();
166: ((SettableConfigItem) configFactory().l2DSOConfig()
167: .listenPort()).setValue(dsoPort);
168: ((SettableConfigItem) configFactory().l2CommonConfig()
169: .jmxPort()).setValue(adminPort);
170: if (!canRunProxyConnect())
171: configFactory().addServerToL1Config(null, dsoPort, -1);
172: }
173:
174: if (canRunProxyConnect()) {
175: setupProxyConnect(helper, portChooser);
176: }
177:
178: this .doSetUp(this );
179:
180: if (isCrashy() && canRunCrash()) {
181: crashTestState = new TestState(false);
182: crasher = new ServerCrasher(serverControl, helper
183: .getServerCrasherConfig().getRestartInterval(),
184: helper.getServerCrasherConfig().isCrashy(),
185: crashTestState, proxyMgr);
186: if (canRunProxyConnect())
187: crasher.setProxyConnectMode(true);
188: crasher.startAutocrash();
189: }
190: }
191:
192: protected ProxyConnectManager getProxyConnectManager() {
193: return this .proxyMgr;
194: }
195:
196: private final void addTestTcPropertiesFile(List jvmArgs) {
197: URL url = getClass().getResource(
198: "/com/tc/properties/tests.properties");
199: if (url == null) {
200: // System.err.println("\n\n ##### No tests.properties defined for this module \n\n");
201: return;
202: }
203: String pathToTestTcProperties = url.getPath();
204: if (pathToTestTcProperties == null
205: || pathToTestTcProperties.equals("")) {
206: // System.err.println("\n\n ##### No path to tests.properties defined \n\n");
207: return;
208: }
209: // System.err.println("\n\n ##### -Dcom.tc.properties=" + pathToTestTcProperties + "\n\n");
210: jvmArgs.add("-Dcom.tc.properties=" + pathToTestTcProperties);
211: }
212:
213: private final void setUpActivePassiveServers(
214: PortChooser portChooser, List jvmArgs) throws Exception {
215: controlledCrashMode = true;
216: setJavaHome();
217: apSetupManager = new ActivePassiveTestSetupManager();
218: setupActivePassiveTest(apSetupManager);
219: apServerManager = new ActivePassiveServerManager(
220: mode()
221: .equals(
222: TestConfigObject.TRANSPARENT_TESTS_MODE_ACTIVE_PASSIVE),
223: getTempDirectory(), portChooser,
224: ActivePassiveServerConfigCreator.DEV_MODE,
225: apSetupManager, javaHome, configFactory(), jvmArgs);
226: apServerManager.addServersToL1Config(configFactory);
227: }
228:
229: protected void setupActivePassiveTest(
230: ActivePassiveTestSetupManager setupManager) {
231: throw new AssertionError(
232: "The sub-class (test) should override this method.");
233: }
234:
235: protected void setupConfig(
236: TestTVSConfigurationSetupManagerFactory configFactory) {
237: // do nothing
238: }
239:
240: private final void setupProxyConnect(RestartTestHelper helper,
241: PortChooser portChooser) throws Exception {
242: int dsoPort = 0;
243: int jmxPort = 0;
244:
245: if (helper != null) {
246: dsoPort = helper.getServerPort();
247: jmxPort = helper.getAdminPort();
248: // for crash+proxy, set crash interval to 60 sec
249: helper.getServerCrasherConfig().setRestartInterval(
250: 60 * 1000);
251: } else if (isActivePassive() && canRunActivePassive()) {
252: // not doing active-passive for proxy yet
253: throw new AssertionError(
254: "Proxy-connect is yet not running with active-passive mode");
255: } else {
256: dsoPort = portChooser.chooseRandomPort();
257: jmxPort = portChooser.chooseRandomPort();
258: }
259:
260: int dsoProxyPort = portChooser.chooseRandomPort();
261:
262: proxyMgr.setDsoPort(dsoPort);
263: proxyMgr.setProxyPort(dsoProxyPort);
264: proxyMgr.setupProxy();
265: setupProxyConnectTest(proxyMgr);
266:
267: ((SettableConfigItem) configFactory().l2DSOConfig()
268: .listenPort()).setValue(dsoPort);
269: ((SettableConfigItem) configFactory().l2CommonConfig()
270: .jmxPort()).setValue(jmxPort);
271: configFactory().addServerToL1Config(null, dsoProxyPort, -1);
272: }
273:
274: protected void setupProxyConnectTest(ProxyConnectManager mgr) {
275: /*
276: * subclass can overwrite to change the test parameters.
277: */
278: mgr.setProxyWaitTime(20 * 1000);
279: mgr.setProxyDownTime(100);
280: }
281:
282: protected boolean useExternalProcess() {
283: return getTestConfigObject().isL2StartupModeExternal();
284: }
285:
286: // only used by regular system tests (not crash or active-passive)
287: protected final void setUpControlledServer(
288: TestTVSConfigurationSetupManagerFactory factory,
289: DSOClientConfigHelper helper, int serverPort,
290: int adminPort, String configFile) throws Exception {
291: setUpControlledServer(factory, helper, serverPort, adminPort,
292: configFile, null);
293: }
294:
295: // used by ResolveTwoActiveServersTest... only works with 2 servers !!
296: protected final void setUpForMultipleExternalProcesses(
297: TestTVSConfigurationSetupManagerFactory factory,
298: DSOClientConfigHelper helper, int[] dsoPorts,
299: int[] jmxPorts, int[] l2GroupPorts, int[] proxyPorts,
300: String[] serverNames, File[] configFiles) throws Exception {
301: assertEquals(dsoPorts.length, 2);
302:
303: controlledCrashMode = true;
304: setJavaHome();
305: serverControls = new ServerControl[dsoPorts.length];
306:
307: proxies = new TCPProxy[2];
308:
309: for (int i = 0; i < 2; i++) {
310: proxies[i] = new TCPProxy(proxyPorts[i], InetAddress
311: .getLocalHost(), l2GroupPorts[i], 0L, false,
312: new File("."));
313: proxies[i].setReuseAddress(true);
314: serverControls[i] = new ExtraProcessServerControl(
315: "localhost", dsoPorts[i], jmxPorts[i],
316: configFiles[i].getAbsolutePath(), true,
317: serverNames[i], null, javaHome, true);
318: }
319: setUp(factory, helper, true);
320: }
321:
322: protected final void setUpControlledServer(
323: TestTVSConfigurationSetupManagerFactory factory,
324: DSOClientConfigHelper helper, int serverPort,
325: int adminPort, String configFile, List jvmArgs)
326: throws Exception {
327: controlledCrashMode = true;
328: if (jvmArgs == null) {
329: jvmArgs = new ArrayList();
330: }
331: addTestTcPropertiesFile(jvmArgs);
332: setUpExternalProcess(factory, helper, serverPort, adminPort,
333: configFile, jvmArgs);
334: }
335:
336: protected void setUpExternalProcess(
337: TestTVSConfigurationSetupManagerFactory factory,
338: DSOClientConfigHelper helper, int serverPort,
339: int adminPort, String configFile, List jvmArgs)
340: throws Exception {
341: setJavaHome();
342: assertNotNull(jvmArgs);
343: serverControl = new ExtraProcessServerControl("localhost",
344: serverPort, adminPort, configFile, true, javaHome,
345: jvmArgs);
346: setUp(factory, helper);
347:
348: ((SettableConfigItem) configFactory().l2DSOConfig()
349: .listenPort()).setValue(serverPort);
350: ((SettableConfigItem) configFactory().l2CommonConfig()
351: .jmxPort()).setValue(adminPort);
352: configFactory()
353: .addServerToL1Config(null, serverPort, adminPort);
354: }
355:
356: private final void setUp(
357: TestTVSConfigurationSetupManagerFactory factory,
358: DSOClientConfigHelper helper) throws Exception {
359: setUp(factory, helper, false);
360: }
361:
362: private final void setUp(
363: TestTVSConfigurationSetupManagerFactory factory,
364: DSOClientConfigHelper helper, boolean serverControlsSet)
365: throws Exception {
366: super .setUp();
367: this .configFactory = factory;
368: this .configHelper = helper;
369: if (serverControlsSet) {
370: transparentAppConfig = new TransparentAppConfig(
371: getApplicationClass().getName(),
372: new TestGlobalIdGenerator(), DEFAULT_CLIENT_COUNT,
373: DEFAULT_INTENSITY, serverControls, proxies);
374: } else {
375: transparentAppConfig = new TransparentAppConfig(
376: getApplicationClass().getName(),
377: new TestGlobalIdGenerator(), DEFAULT_CLIENT_COUNT,
378: DEFAULT_INTENSITY, serverControl,
379: DEFAULT_VALIDATOR_COUNT,
380: DEFAULT_ADAPTED_MUTATOR_COUNT,
381: DEFAULT_ADAPTED_VALIDATOR_COUNT);
382: }
383:
384: transparentAppConfig.setAttribute(
385: TransparentAppConfig.PROXY_CONNECT_MGR, proxyMgr);
386: }
387:
388: protected synchronized final String mode() {
389: if (mode == null) {
390: mode = getTestConfigObject().transparentTestsMode();
391: }
392:
393: return mode;
394: }
395:
396: public void doSetUp(TransparentTestIface t) throws Exception {
397: // Nothing here, by default
398: }
399:
400: private boolean isCrashy() {
401: return TestConfigObject.TRANSPARENT_TESTS_MODE_CRASH
402: .equals(mode());
403: }
404:
405: private boolean isActivePassive() {
406: return TestConfigObject.TRANSPARENT_TESTS_MODE_ACTIVE_PASSIVE
407: .equals(mode());
408: }
409:
410: public DSOClientConfigHelper getConfigHelper() {
411: return this .configHelper;
412: }
413:
414: public TVSConfigurationSetupManagerFactory getConfigFactory() {
415: return configFactory;
416: }
417:
418: public DistributedTestRunnerConfig getRunnerConfig() {
419: return this .runnerConfig;
420: }
421:
422: public void setApplicationConfigBuilder(
423: ApplicationConfigBuilder builder) {
424: this .possibleApplicationConfigBuilder = builder;
425: }
426:
427: public TransparentAppConfig getTransparentAppConfig() {
428: return this .transparentAppConfig;
429: }
430:
431: protected ApplicationConfigBuilder getApplicationConfigBuilder() {
432: if (possibleApplicationConfigBuilder != null)
433: return possibleApplicationConfigBuilder;
434: else
435: return transparentAppConfig;
436: }
437:
438: protected abstract Class getApplicationClass();
439:
440: protected Map getOptionalAttributes() {
441: return new HashMap();
442: }
443:
444: String getServerPortProp() {
445: return System.getProperty("test.base.server.port");
446: }
447:
448: private boolean getStartServer() {
449: return getServerPortProp() == null
450: && mode().equals(
451: TestConfigObject.TRANSPARENT_TESTS_MODE_NORMAL)
452: && !controlledCrashMode && !useExternalProcess();
453: }
454:
455: public void initializeTestRunner() throws Exception {
456: initializeTestRunner(false);
457: }
458:
459: public void initializeTestRunner(boolean isMutateValidateTest)
460: throws Exception {
461: this .runner = new DistributedTestRunner(runnerConfig,
462: configFactory, configHelper, getApplicationClass(),
463: getOptionalAttributes(), getApplicationConfigBuilder()
464: .newApplicationConfig(), getStartServer(),
465: isMutateValidateTest,
466: (isActivePassive() && canRunActivePassive()),
467: apServerManager, transparentAppConfig);
468: }
469:
470: protected boolean canRun() {
471: return (mode().equals(
472: TestConfigObject.TRANSPARENT_TESTS_MODE_NORMAL) && canRunNormal())
473: || (mode().equals(
474: TestConfigObject.TRANSPARENT_TESTS_MODE_CRASH) && canRunCrash())
475: || (mode()
476: .equals(
477: TestConfigObject.TRANSPARENT_TESTS_MODE_ACTIVE_PASSIVE) && canRunActivePassive());
478: }
479:
480: protected boolean canRunNormal() {
481: return true;
482: }
483:
484: protected boolean canRunCrash() {
485: return false;
486: }
487:
488: protected boolean canRunActivePassive() {
489: return false;
490: }
491:
492: protected boolean canRunProxyConnect() {
493: return false;
494: }
495:
496: protected boolean canSkipL1ReconnectCheck() {
497: return false;
498: }
499:
500: protected boolean enableManualProxyConnectControl() {
501: return false;
502: }
503:
504: protected boolean enableL1Reconnect() {
505: return false;
506: }
507:
508: protected void startServerControlsAndProxies() throws Exception {
509: assertEquals(serverControls.length, 2);
510: for (int i = 0; i < serverControls.length; i++) {
511: serverControls[i].start();
512:
513: // make sure that the first server becomes active
514: if (i == 0) {
515: Thread.sleep(10 * 1000);
516: } else {
517: proxies[1].start();
518: proxies[0].start();
519: }
520: }
521: }
522:
523: public void test() throws Exception {
524: if (canRun()) {
525: if (controlledCrashMode && isActivePassive()
526: && apServerManager != null) {
527: // active passive tests
528: apServerManager.startServers();
529: } else if (controlledCrashMode && serverControls != null
530: && proxies != null) {
531: // ResolveTwoActiveServersTest that use proxies between l2s
532: startServerControlsAndProxies();
533: } else if (serverControl != null && crasher == null) {
534: // normal mode tests
535: serverControl.start();
536: }
537: // NOTE: for crash tests the server needs to be started by the ServerCrasher.. timing issue
538:
539: this .runner.startServer();
540: if (canRunProxyConnect()) {
541: proxyMgr.proxyUp();
542:
543: if (!enableManualProxyConnectControl()) {
544: proxyMgr.startProxyTest();
545: }
546: }
547: this .runner.run();
548:
549: if (this .runner.executionTimedOut()
550: || this .runner.startTimedOut()) {
551: try {
552: System.err
553: .println("##### About to shutdown server crasher");
554: synchronized (crashTestState) {
555: crashTestState.setTestState(TestState.STOPPING);
556: }
557: System.err.println("##### About to dump server");
558: dumpServers();
559: } finally {
560: if (pid != 0) {
561: System.out
562: .println("Thread dumping test process");
563: ThreadDump.dumpThreadsMany(
564: getThreadDumpCount(),
565: getThreadDumpInterval());
566: }
567: }
568: }
569:
570: if (!this .runner.success()) {
571: AssertionFailedError e = new AssertionFailedError(
572: new ErrorContextFormatter(this .runner
573: .getErrors())
574: .formatForExceptionMessage());
575: throw e;
576: }
577: } else {
578: System.err.println("NOTE: " + getClass().getName()
579: + " can't be run in mode '" + mode()
580: + "', and thus will be skipped.");
581: }
582: }
583:
584: private void dumpServers() throws Exception {
585: if (serverControl != null && serverControl.isRunning()) {
586: System.out.println("Dumping server=["
587: + serverControl.getDsoPort() + "]");
588: dumpServerControl(serverControl);
589: }
590:
591: if (apServerManager != null) {
592: apServerManager.dumpAllServers(pid, getThreadDumpCount(),
593: getThreadDumpInterval());
594: pid = apServerManager.getPid();
595: }
596:
597: if (serverControls != null) {
598: for (int i = 0; i < serverControls.length; i++) {
599: dumpServerControl(serverControls[i]);
600: }
601: }
602:
603: if (runner != null) {
604: runner.dumpServer();
605: } else {
606: System.err.println("Runner is null !!");
607: }
608: }
609:
610: private void dumpServerControl(ServerControl control)
611: throws Exception {
612: JMXConnector jmxConnector = ActivePassiveServerManager
613: .getJMXConnector(control.getAdminPort());
614: MBeanServerConnection mbs = jmxConnector
615: .getMBeanServerConnection();
616: L2DumperMBean mbean = (L2DumperMBean) MBeanServerInvocationHandler
617: .newProxyInstance(mbs, L2MBeanNames.DUMPER,
618: L2DumperMBean.class, true);
619: while (true) {
620: try {
621: mbean.doServerDump();
622: break;
623: } catch (Exception e) {
624: System.out
625: .println("Could not find L2DumperMBean... sleep for 1 sec.");
626: Thread.sleep(1000);
627: }
628: }
629:
630: if (pid != 0) {
631: mbean.setThreadDumpCount(getThreadDumpCount());
632: mbean.setThreadDumpInterval(getThreadDumpInterval());
633: System.out.println("Thread dumping server=["
634: + serverControl.getDsoPort() + "] pid=[" + pid
635: + "]");
636: pid = mbean.doThreadDump();
637: }
638: jmxConnector.close();
639: }
640:
641: protected void tearDown() throws Exception {
642: if (controlledCrashMode) {
643: if (isActivePassive() && canRunActivePassive()) {
644: System.out.println("Currently running java processes: "
645: + ProcessInfo.ps_grep_java());
646: apServerManager.stopAllServers();
647: } else if (isCrashy() && canRunCrash()) {
648: synchronized (crashTestState) {
649: crashTestState.setTestState(TestState.STOPPING);
650: if (serverControl.isRunning()) {
651: serverControl.shutdown();
652: }
653: }
654: }
655: }
656:
657: if (serverControls != null) {
658: for (int i = 0; i < serverControls.length; i++) {
659: if (serverControls[i].isRunning()) {
660: serverControls[i].shutdown();
661: }
662: }
663: }
664:
665: if (serverControl != null && serverControl.isRunning()) {
666: serverControl.shutdown();
667: }
668:
669: super .tearDown();
670: }
671:
672: protected void doDumpServerDetails() {
673: try {
674: dumpServers();
675: } catch (Exception ex) {
676: ex.printStackTrace();
677: }
678: }
679:
680: private static final class ErrorContextFormatter {
681: private final Collection contexts;
682: private final StringBuffer buf = new StringBuffer();
683:
684: public ErrorContextFormatter(Collection contexts) {
685: this .contexts = contexts;
686: }
687:
688: private void div() {
689: buf
690: .append("\n**************************************************************\n");
691: }
692:
693: private void println(Object message) {
694: buf.append(message + "\n");
695: }
696:
697: public String formatForExceptionMessage() {
698: buf.delete(0, buf.length());
699: div();
700: println("There are " + contexts.size() + " error contexts:");
701: int count = 1;
702: for (Iterator i = contexts.iterator(); i.hasNext();) {
703: ErrorContext ctxt = (ErrorContext) i.next();
704: println("Error context " + count + "\n");
705: println(ctxt);
706: count++;
707: }
708: println("End error contexts.");
709: div();
710: return buf.toString();
711: }
712: }
713:
714: protected File writeMinimalConfig(int port, int adminPort) {
715: TerracottaConfigBuilder builder = createConfigBuilder(port,
716: adminPort);
717: FileOutputStream out = null;
718: File configFile = null;
719: try {
720: configFile = getTempFile("config-file.xml");
721: out = new FileOutputStream(configFile);
722: CopyUtils.copy(builder.toString(), out);
723: } catch (Exception e) {
724: throw Assert.failure("Can't create config file", e);
725: } finally {
726: try {
727: out.close();
728: } catch (Exception e) { /* oh well, we tried */
729: }
730: }
731:
732: return configFile;
733: }
734:
735: protected TerracottaConfigBuilder createConfigBuilder(int port,
736: int adminPort) {
737: TerracottaConfigBuilder out = new TerracottaConfigBuilder();
738:
739: out.getServers().getL2s()[0].setDSOPort(port);
740: out.getServers().getL2s()[0].setJMXPort(adminPort);
741:
742: return out;
743: }
744:
745: /*
746: * State inner class
747: */
748:
749: }
|