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.tc.test.restart;
006:
007: import org.apache.commons.io.FileUtils;
008:
009: import com.tc.config.schema.MockIllegalConfigurationChangeHandler;
010: import com.tc.config.schema.setup.StandardTVSConfigurationSetupManagerFactory;
011: import com.tc.config.schema.setup.TestTVSConfigurationSetupManagerFactory;
012: import com.tc.config.schema.test.L2ConfigBuilder;
013: import com.tc.config.schema.test.L2SConfigBuilder;
014: import com.tc.config.schema.test.TerracottaConfigBuilder;
015: import com.tc.logging.TCLogger;
016: import com.tc.logging.TCLogging;
017: import com.tc.objectserver.control.ExtraProcessServerControl;
018: import com.tc.objectserver.control.NullServerControl;
019: import com.tc.objectserver.control.ServerControl;
020: import com.tc.objectserver.control.ExtraProcessServerControl.DebugParams;
021: import com.tc.test.TestConfigObject;
022: import com.tc.util.PortChooser;
023: import com.tctest.restart.TestThreadGroup;
024: import com.terracottatech.config.PersistenceMode;
025:
026: import java.io.File;
027: import java.io.FileNotFoundException;
028: import java.io.FileOutputStream;
029: import java.io.PrintWriter;
030: import java.util.ArrayList;
031: import java.util.Collection;
032: import java.util.List;
033:
034: public class RestartTestEnvironment {
035:
036: public static final OperatingMode DEV_MODE = new OperatingMode();
037: public static final OperatingMode PROD_MODE = new OperatingMode();
038:
039: private static TCLogger logger = TCLogging
040: .getTestingLogger(RestartTestEnvironment.class);
041: private final PortChooser portChooser;
042: private StandardTVSConfigurationSetupManagerFactory config;
043: private File configFile;
044:
045: private File dbhome;
046: private ServerControl server;
047: private final ServerControl serverWrapper = new ServerWrapper();
048: private TestThreadGroup threadGroup;
049:
050: private boolean isPersistent = true;
051: private boolean isParanoid = true;
052: private final File tempDirectory;
053: private boolean setUp;
054: private boolean mergeServerOutput = true;
055: private int serverPort;
056: private int adminPort;
057: private final OperatingMode operatingMode;
058: private final TestTVSConfigurationSetupManagerFactory configFactory;
059:
060: public RestartTestEnvironment(File tempDirectory,
061: PortChooser portChooser, OperatingMode operatingMode) {
062: this (tempDirectory, portChooser, operatingMode, null);
063: }
064:
065: public RestartTestEnvironment(File tempDirectory,
066: PortChooser portChooser, OperatingMode operatingMode,
067: TestTVSConfigurationSetupManagerFactory configFactory) {
068: this .tempDirectory = tempDirectory;
069: this .portChooser = portChooser;
070: this .operatingMode = operatingMode;
071: this .configFactory = configFactory;
072: if (!tempDirectory.isDirectory()) {
073: //
074: throw new AssertionError(
075: "Temp directory is not a directory: "
076: + tempDirectory);
077: }
078: this .configFile = new File(this .tempDirectory,
079: "restart-test-config.xml");
080: }
081:
082: public void setIsPersistent(boolean b) {
083: isPersistent = b;
084: }
085:
086: public void setIsParanoid(boolean b) {
087: this .isParanoid = b;
088: }
089:
090: public void setUp() throws Exception {
091: writeL2Config();
092: initConfig();
093:
094: dbhome = new File(this .tempDirectory, "l2-data/objectdb");
095: System.err.println("DBHome: " + dbhome.getAbsolutePath());
096: System.out.println("dbhome: " + dbhome);
097: if (dbhome.exists())
098: FileUtils.cleanDirectory(dbhome);
099: if (server != null && server.isRunning()) {
100: logger.info("L2 is running... Shutting it down.");
101: server.shutdown();
102: for (int i = 0; i < 3 && server.isRunning(); i++) {
103: Thread.sleep(1000);
104: }
105: }
106: logger.info("Making sure L2 isn't running...");
107: if (server != null && server.isRunning())
108: throw new AssertionError(
109: "L2 is currently running, but shouldn't be.");
110: threadGroup = new TestThreadGroup(Thread.currentThread()
111: .getThreadGroup(), "TEST THREAD GROUP");
112:
113: this .server = new NullServerControl();
114: this .setUp = true;
115: }
116:
117: private void initConfig() throws Exception {
118: // FIXME 2005-12-01 andrew -- This MockIllegalConfigurationChangeHandler probably isn't right. We should fix it.
119:
120: config = new StandardTVSConfigurationSetupManagerFactory(
121: new String[] {
122: StandardTVSConfigurationSetupManagerFactory.CONFIG_SPEC_ARGUMENT_WORD,
123: this .configFile.getAbsolutePath() }, true,
124: new MockIllegalConfigurationChangeHandler());
125: }
126:
127: private void writeL2Config() throws Exception {
128: assertServerOff();
129:
130: TerracottaConfigBuilder builder = TerracottaConfigBuilder
131: .newMinimalInstance();
132:
133: String configurationModel;
134: if (operatingMode == DEV_MODE) {
135: configurationModel = "development";
136: } else if (operatingMode == PROD_MODE) {
137: configurationModel = "production";
138: } else {
139: throw new AssertionError("Unknown operating mode.");
140: }
141: builder.getSystem().setConfigurationModel(configurationModel);
142:
143: String persistenceMode = L2ConfigBuilder.PERSISTENCE_MODE_TEMPORARY_SWAP_ONLY;
144:
145: if (isPersistent && isParanoid) {
146: // for crash tests
147: persistenceMode = L2ConfigBuilder.PERSISTENCE_MODE_PERMANENT_STORE;
148: } else if (isPersistent) {
149:
150: // for restart tests
151: persistenceMode = L2ConfigBuilder.PERSISTENCE_MODE_TEMPORARY_SWAP_ONLY;
152:
153: // for normal mode tests
154: if (configFactory.getPersistenceMode() == PersistenceMode.PERMANENT_STORE) {
155: persistenceMode = L2ConfigBuilder.PERSISTENCE_MODE_PERMANENT_STORE;
156: }
157:
158: }
159:
160: L2ConfigBuilder l2 = new L2ConfigBuilder();
161: l2.setDSOPort(serverPort);
162: l2.setJMXPort(adminPort);
163: l2.setData(tempDirectory.getAbsolutePath());
164: l2.setPersistenceMode(persistenceMode);
165: if (configFactory != null) {
166: l2.setGCEnabled(configFactory.getGCEnabled());
167: l2.setGCVerbose(configFactory.getGCVerbose());
168: l2.setGCInterval(configFactory.getGCIntervalInSec());
169: }
170: L2ConfigBuilder[] l2s = new L2ConfigBuilder[] { l2 };
171: L2SConfigBuilder servers = new L2SConfigBuilder();
172: servers.setL2s(l2s);
173: builder.setServers(servers);
174:
175: String configAsString = builder.toString();
176:
177: System.err.println("Writing config to file:"
178: + configFile.getAbsolutePath() + configAsString);
179: FileOutputStream fileOutputStream = new FileOutputStream(
180: configFile);
181: PrintWriter out = new PrintWriter((fileOutputStream));
182: out.println(configAsString);
183: out.flush();
184: out.close();
185:
186: initConfig();
187: }
188:
189: public Collection getThreadGroupErrors() {
190: return this .threadGroup.getErrors();
191: }
192:
193: public void startNewClientThread(Runnable runnable) {
194: new Thread(this .threadGroup, runnable).start();
195: }
196:
197: public boolean hasThreadGroupErrors() {
198: return threadGroup.getErrors().size() > 0;
199: }
200:
201: public boolean hasActiveClients() {
202: return this .threadGroup.activeCount() > 0;
203: }
204:
205: public ThreadGroup getThreadGroup() {
206: return this .threadGroup;
207: }
208:
209: public ServerControl getServer() {
210: return this .server;
211: }
212:
213: public void startServer(long timeout) throws Exception {
214: assertServerOff();
215: assertSetUp();
216: server.start();
217: }
218:
219: public void shutdownServer() throws Exception {
220: assertServerNotNull();
221: server.shutdown();
222: }
223:
224: public ServerControl newExtraProcessServer(List jvmArgs)
225: throws FileNotFoundException {
226: assertServerOff();
227: File javaHome = null;
228: try {
229: String javaHomeString = TestConfigObject.getInstance()
230: .getL2StartupJavaHome();
231: if (javaHomeString != null) {
232: javaHome = new File(javaHomeString);
233: }
234: } catch (Exception e) {
235: // ignore, leaving javaHome as null
236: }
237: this .server = new ExtraProcessServerControl(new DebugParams(),
238: "localhost", serverPort, adminPort, this .configFile
239: .getAbsolutePath(), mergeServerOutput,
240: javaHome, jvmArgs);
241: return serverWrapper;
242: }
243:
244: public ServerControl newExtraProcessServer()
245: throws FileNotFoundException {
246: return (newExtraProcessServer(new ArrayList()));
247: }
248:
249: /*
250: Commented out by jvoegele since this method is not called from anywhere and it creates a dependency
251: on the deploy module. The following imports were also removed as a result of removing this method:
252: import com.tc.config.schema.setup.ConfigurationSetupException;
253: import com.tc.objectserver.control.IntraProcessServerControl;
254:
255: public ServerControl newIntraProcessServer() throws ConfigurationSetupException {
256: assertServerOff();
257: this.server = new IntraProcessServerControl(this.config.createL2TVSConfigurationSetupManager(null), "localhost");
258: return serverWrapper;
259: }
260: */
261:
262: private void assertServerNotNull() {
263: if (this .server == null)
264: throw new AssertionError("Server is null.");
265: }
266:
267: private void assertServerOff() {
268: if (this .server != null && this .server.isRunning()) {
269: //
270: throw new AssertionError("Server is not off.");
271: }
272: }
273:
274: private void assertServerOn() {
275: assertServerNotNull();
276: if (!this .server.isRunning()) {
277: throw new AssertionError("Server is not on.");
278: }
279: }
280:
281: private void assertSetUp() {
282: if (!this .setUp)
283: throw new AssertionError("Not set up.");
284: }
285:
286: public File getDBHome() {
287: return this .dbhome;
288: }
289:
290: public void setServerPort(int i) {
291: this .serverPort = i;
292: }
293:
294: public void setAdminPort(int i) {
295: this .adminPort = i;
296: }
297:
298: public int chooseServerPort() {
299: this .serverPort = portChooser.chooseRandomPort();
300: return this .serverPort;
301: }
302:
303: public int chooseAdminPort() {
304: this .adminPort = portChooser.chooseRandomPort();
305: return this .adminPort;
306: }
307:
308: public void choosePorts() {
309: chooseServerPort();
310: chooseAdminPort();
311: }
312:
313: public int getServerPort() {
314: return this .serverPort;
315: }
316:
317: public int getAdminPort() {
318: return this .adminPort;
319: }
320:
321: public static final class OperatingMode {
322: private OperatingMode() {
323: //
324: }
325: }
326:
327: private final class ServerWrapper implements ServerControl {
328:
329: public void mergeSTDOUT() {
330: assertServerOff();
331: server.mergeSTDOUT();
332: }
333:
334: public void mergeSTDERR() {
335: assertServerOff();
336: server.mergeSTDERR();
337: }
338:
339: public void attemptShutdown() throws Exception {
340: assertServerOn();
341: server.attemptShutdown();
342: }
343:
344: public void shutdown() throws Exception {
345: assertServerOn();
346: server.shutdown();
347: }
348:
349: public void crash() throws Exception {
350: assertServerOn();
351: server.crash();
352: }
353:
354: public void start() throws Exception {
355: assertSetUp();
356: assertServerNotNull();
357: server.start();
358: }
359:
360: public boolean isRunning() {
361: assertServerNotNull();
362: return server.isRunning();
363: }
364:
365: public void waitUntilShutdown() throws Exception {
366: assertServerNotNull();
367: server.waitUntilShutdown();
368: }
369:
370: public int getDsoPort() {
371: assertServerNotNull();
372: return server.getDsoPort();
373: }
374:
375: public int getAdminPort() {
376: assertServerNotNull();
377: return server.getAdminPort();
378: }
379: }
380: }
|