0001: /*
0002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003: *
0004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * The contents of this file are subject to the terms of either the GNU
0007: * General Public License Version 2 only ("GPL") or the Common
0008: * Development and Distribution License("CDDL") (collectively, the
0009: * "License"). You may not use this file except in compliance with the
0010: * License. You can obtain a copy of the License at
0011: * http://www.netbeans.org/cddl-gplv2.html
0012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013: * specific language governing permissions and limitations under the
0014: * License. When distributing the software, include this License Header
0015: * Notice in each file and include the License file at
0016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
0017: * particular file as subject to the "Classpath" exception as provided
0018: * by Sun in the GPL Version 2 section of the License file that
0019: * accompanied this code. If applicable, add the following below the
0020: * License Header, with the fields enclosed by brackets [] replaced by
0021: * your own identifying information:
0022: * "Portions Copyrighted [year] [name of copyright owner]"
0023: *
0024: * Contributor(s):
0025: *
0026: * The Original Software is NetBeans. The Initial Developer of the Original
0027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
0028: * Microsystems, Inc. All Rights Reserved.
0029: *
0030: * If you wish your version of this file to be governed by only the CDDL
0031: * or only the GPL Version 2, indicate your decision by adding
0032: * "[Contributor] elects to include this software in this distribution
0033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034: * single choice of license, a recipient has the option to distribute
0035: * your version of this file under either the CDDL, the GPL Version 2 or
0036: * to extend the choice of license to its licensees as provided above.
0037: * However, if you add GPL Version 2 code and therefore, elected the GPL
0038: * Version 2 license, then the option applies only if the new code is
0039: * made subject to such option by the copyright holder.
0040: */
0041:
0042: package org.netbeans;
0043:
0044: import java.io.*;
0045: import java.util.logging.Level;
0046: import org.netbeans.junit.*;
0047: import java.util.*;
0048: import java.util.logging.Logger;
0049: import org.openide.util.RequestProcessor;
0050:
0051: /**
0052: * Test the command-line-interface handler.
0053: * @author Jaroslav Tulach
0054: */
0055: public class CLIHandlerTest extends NbTestCase {
0056:
0057: private static ByteArrayInputStream nullInput = new ByteArrayInputStream(
0058: new byte[0]);
0059: private static ByteArrayOutputStream nullOutput = new ByteArrayOutputStream();
0060:
0061: private Logger LOG;
0062:
0063: public CLIHandlerTest(String name) {
0064: super (name);
0065: }
0066:
0067: public static junit.framework.Test suite() {
0068: //return new CLIHandlerTest("testCLIHandlersCanChangeLocationOfLockFile");
0069: return new NbTestSuite(CLIHandlerTest.class);
0070: }
0071:
0072: protected void setUp() throws Exception {
0073: LOG = Logger.getLogger("TEST-" + getName());
0074:
0075: super .setUp();
0076:
0077: // all handlers shall be executed immediatelly
0078: CLIHandler.finishInitialization(false);
0079:
0080: // setups a temporary file
0081: String p = getWorkDirPath();
0082: if (p == null) {
0083: p = System.getProperty("java.io.tmpdir");
0084: }
0085: String tmp = p;
0086: assertNotNull(tmp);
0087: System.getProperties().put("netbeans.user", tmp);
0088:
0089: File f = new File(tmp, "lock");
0090: if (f.exists()) {
0091: assertTrue("Clean up previous mess", f.delete());
0092: assertTrue(!f.exists());
0093: }
0094: }
0095:
0096: protected Level logLevel() {
0097: return Level.FINEST;
0098: }
0099:
0100: public void testFileExistsButItCannotBeRead() throws Exception {
0101: // just creates the file and blocks
0102: InitializeRunner runner = new InitializeRunner(10);
0103:
0104: // blocks when operation fails
0105: InitializeRunner second = new InitializeRunner(85);
0106:
0107: for (int i = 0; i < 3; i++) {
0108: second.next();
0109: }
0110:
0111: // finishes the code
0112: runner.next();
0113:
0114: assertNotNull("Runner succeeded to allocate the file", runner
0115: .resultFile());
0116:
0117: // let the second code go on as well
0118: second.next();
0119:
0120: assertEquals("The same file has been allocated", runner
0121: .resultFile(), second.resultFile());
0122: }
0123:
0124: public void testFileExistsButTheServerCannotBeContacted()
0125: throws Exception {
0126: // start the server and block
0127: InitializeRunner runner = new InitializeRunner(65);
0128:
0129: assertNotNull("File created", runner.resultFile());
0130: assertTrue("Port allocated", runner.resultPort() != 0);
0131:
0132: // blocks when operation fails
0133: InitializeRunner second = new InitializeRunner(85);
0134: // second try should be ok
0135: second.next();
0136:
0137: assertNotNull("Previous file deleted and new one created",
0138: second.resultFile());
0139: assertTrue("Another port allocated",
0140: second.resultPort() != runner.resultPort());
0141:
0142: }
0143:
0144: public void testFileExistsHasPortButNotTheKey() throws Exception {
0145: // start the server and block
0146: Integer block = new Integer(97);
0147: InitializeRunner runner;
0148: synchronized (block) {
0149: runner = new InitializeRunner(block, true);
0150: // the initialization code can finish without reaching 97
0151: runner.waitResult();
0152: }
0153:
0154: assertTrue("Port allocated", runner.resultPort() != 0);
0155:
0156: // blocks after read the keys from the file
0157: InitializeRunner second = new InitializeRunner(94);
0158:
0159: // let the CLI Secure Handler finish
0160: synchronized (block) {
0161: block.notifyAll();
0162: }
0163: // let the test go beyond 97 to the end of file
0164: assertNotNull("File created", runner.resultFile());
0165:
0166: // let the second finish
0167: second.next();
0168:
0169: assertEquals("Still the same file", runner.resultFile(), second
0170: .resultFile());
0171: assertEquals("Another port allocated", second.resultPort(),
0172: runner.resultPort());
0173: }
0174:
0175: public void testHelpIsPrinted() throws Exception {
0176: class UserDir extends CLIHandler {
0177: private int cnt;
0178: private boolean doCheck;
0179:
0180: public UserDir() {
0181: super (WHEN_BOOT);
0182: }
0183:
0184: protected int cli(Args args) {
0185: if (!doCheck) {
0186: return 0;
0187: }
0188:
0189: cnt++;
0190:
0191: for (String a : args.getArguments()) {
0192: if ("--help".equals(a)) {
0193: return 0;
0194: }
0195: }
0196: return 5;
0197: }
0198:
0199: protected void usage(PrintWriter w) {
0200: w.println("this is a help");
0201: }
0202: }
0203: UserDir ud = new UserDir();
0204:
0205: ByteArrayOutputStream os = new ByteArrayOutputStream();
0206:
0207: CLIHandler.Status res = cliInitialize(
0208: new String[] { "--help" }, new CLIHandler[] { ud },
0209: nullInput, os, nullOutput);
0210: assertEquals("Help returns 2", 2, res.getExitCode());
0211:
0212: if (os.toString().indexOf("help") == -1) {
0213: fail("There should be some help text:\n" + os);
0214: }
0215: }
0216:
0217: public void testHelpIsPassedToRunningServer() throws Exception {
0218: class UserDir extends CLIHandler implements Runnable {
0219: private int cnt;
0220: private int usage;
0221: private boolean doCheck;
0222: private CLIHandler.Status res;
0223:
0224: public UserDir() {
0225: super (WHEN_BOOT);
0226: }
0227:
0228: protected int cli(Args args) {
0229: if (!doCheck) {
0230: return 0;
0231: }
0232:
0233: cnt++;
0234:
0235: for (String a : args.getArguments()) {
0236: if ("--help".equals(a)) {
0237: return 0;
0238: }
0239: }
0240: return 5;
0241: }
0242:
0243: protected void usage(PrintWriter w) {
0244: usage++;
0245: }
0246:
0247: public void run() {
0248: res = cliInitialize(new String[] {},
0249: new CLIHandler[] { this }, nullInput,
0250: nullOutput, nullOutput);
0251: }
0252: }
0253: UserDir ud = new UserDir();
0254:
0255: RequestProcessor.getDefault().post(ud).waitFinished();
0256: assertNotNull(ud.res);
0257:
0258: assertNotNull("File created", ud.res.getLockFile());
0259: assertTrue("Port allocated", ud.res.getServerPort() != 0);
0260:
0261: ud.doCheck = true;
0262: CLIHandler.Status res = cliInitialize(
0263: new String[] { "--help" }, new CLIHandler[0],
0264: nullInput, nullOutput, nullOutput);
0265:
0266: assertEquals("Ok exec of help", 2, res.getExitCode());
0267:
0268: assertEquals("No cli called", 0, ud.cnt);
0269: assertEquals("Usage called", 1, ud.usage);
0270:
0271: }
0272:
0273: public void testFileExistsButTheServerCannotBeContactedAndWeDoNotWantToCleanTheFileOnSameHost()
0274: throws Exception {
0275: // start the server and block
0276: InitializeRunner runner = new InitializeRunner(65);
0277:
0278: assertNotNull("File created", runner.resultFile());
0279: assertTrue("Port allocated", runner.resultPort() != 0);
0280:
0281: CLIHandler.Status res = CLIHandler.initialize(
0282: new CLIHandler.Args(new String[0], nullInput,
0283: nullOutput, nullOutput, ""), null,
0284: Collections.EMPTY_LIST, false, false, null);
0285:
0286: assertNotNull("Previous file deleted and new one created", res
0287: .getLockFile());
0288: assertTrue("Another port allocated",
0289: res.getServerPort() != runner.resultPort());
0290: }
0291:
0292: public void testFileExistsButTheServerCannotBeContactedAndWeDoNotWantToCleanTheFileOnOtherHost()
0293: throws Exception {
0294: // start the server and block
0295: InitializeRunner runner = new InitializeRunner(65);
0296:
0297: assertNotNull("File created", runner.resultFile());
0298: assertTrue("Port allocated", runner.resultPort() != 0);
0299:
0300: File f = runner.resultFile();
0301: byte[] arr = new byte[(int) f.length()];
0302: int len = arr.length;
0303: assertTrue(
0304: "We know that the size of the file should be int + key_length + 4 for ip address: ",
0305: len >= 14 && len <= 18);
0306: FileInputStream is = new FileInputStream(f);
0307: assertEquals("Fully read", arr.length, is.read(arr));
0308: is.close();
0309:
0310: byte[] altarr = new byte[18];
0311: for (int i = 0; i < 18; i++) {
0312: altarr[i] = i < 14 ? arr[i] : 1;
0313: }
0314:
0315: // change the IP at the end of the file
0316: FileOutputStream os = new FileOutputStream(f);
0317: os.write(altarr);
0318: os.close();
0319:
0320: CLIHandler.Status res = CLIHandler.initialize(
0321: new CLIHandler.Args(new String[0], nullInput,
0322: nullOutput, nullOutput, ""), null,
0323: Collections.EMPTY_LIST, false, false, null);
0324:
0325: assertEquals("Cannot connect because the IP is different",
0326: CLIHandler.Status.CANNOT_CONNECT, res.getExitCode());
0327: }
0328:
0329: public void testFileExistsButTheKeyIsNotRecognized()
0330: throws Exception {
0331: // start the server be notified when it accepts connection
0332: InitializeRunner runner = new InitializeRunner(65);
0333:
0334: assertNotNull("File created", runner.resultFile());
0335: assertTrue("Port allocated", runner.resultPort() != 0);
0336:
0337: int s = (int) runner.resultFile().length();
0338: byte[] copy = new byte[s];
0339: FileInputStream is = new FileInputStream(runner.resultFile());
0340: assertEquals("Read fully", s, is.read(copy));
0341: is.close();
0342:
0343: // change one byte in the key
0344: copy[4 + 2]++;
0345:
0346: FileOutputStream os = new FileOutputStream(runner.resultFile());
0347: os.write(copy);
0348: os.close();
0349:
0350: // try to connect to previous server be notified as soon as it
0351: // sends request
0352: InitializeRunner second = new InitializeRunner(30);
0353:
0354: // handle the request, say NO
0355: runner.next();
0356:
0357: // read the reply and allocate new port
0358: second.next();
0359:
0360: assertNotNull("Previous file deleted and new one created",
0361: second.resultFile());
0362: assertTrue("Another port allocated",
0363: second.resultPort() != runner.resultPort());
0364: }
0365:
0366: public void testCLIHandlersCanChangeLocationOfLockFile()
0367: throws Exception {
0368: File f = File.createTempFile("suffix", "tmp").getParentFile();
0369: final File dir = new File(f, "subdir");
0370: dir.delete();
0371: assertTrue(dir.exists() || dir.mkdir());
0372:
0373: class UserDir extends CLIHandler {
0374: private int cnt;
0375:
0376: public UserDir() {
0377: super (WHEN_BOOT);
0378: }
0379:
0380: protected int cli(Args args) {
0381: cnt++;
0382: System.setProperty("netbeans.user", dir.toString());
0383: return 0;
0384: }
0385:
0386: protected void usage(PrintWriter w) {
0387: }
0388: }
0389: UserDir ud = new UserDir();
0390:
0391: CLIHandler.Status res = cliInitialize(new String[0], ud,
0392: nullInput, nullOutput, nullOutput, null);
0393: assertNotNull("res: ", res);
0394: assertEquals("Our command line handler is called once", 1,
0395: ud.cnt);
0396: assertEquals("Lock file is created in dir", dir, res
0397: .getLockFile().getParentFile());
0398:
0399: dir.delete();
0400: }
0401:
0402: public void testCLIHandlerCanStopEvaluation() throws Exception {
0403: class H extends CLIHandler {
0404: private int cnt;
0405:
0406: public H() {
0407: super (WHEN_INIT);
0408: }
0409:
0410: protected int cli(Args args) {
0411: cnt++;
0412: return 1;
0413: }
0414:
0415: protected void usage(PrintWriter w) {
0416: }
0417: }
0418: H h1 = new H();
0419: H h2 = new H();
0420:
0421: CLIHandler.Status res = cliInitialize(new String[0], new H[] {
0422: h1, h2 }, nullInput, nullOutput, nullOutput);
0423:
0424: assertEquals("CLI evaluation failed with return code of h1", 1,
0425: res.getExitCode());
0426: assertEquals("First one executed", 1, h1.cnt);
0427: assertEquals("Not the second one", 0, h2.cnt);
0428: }
0429:
0430: public void testWhenInvokedTwiceParamsGoToTheFirstHandler()
0431: throws Exception {
0432: final String[] template = { "Ahoj", "Hello" };
0433: final String currentDir = "MyDir";
0434:
0435: class H extends CLIHandler {
0436: private int cnt;
0437:
0438: public H() {
0439: super (WHEN_INIT);
0440: }
0441:
0442: protected int cli(Args args) {
0443: String[] a = args.getArguments();
0444: String[] t = template;
0445:
0446: assertEquals("Same length", t.length, a.length);
0447: assertEquals("First is same", t[0], a[0]);
0448: assertEquals("Second is same", t[1], a[1]);
0449: assertEquals("Current dir is fine", currentDir, args
0450: .getCurrentDirectory().toString());
0451: return ++cnt;
0452: }
0453:
0454: protected void usage(PrintWriter w) {
0455: }
0456: }
0457: H h1 = new H();
0458:
0459: CLIHandler.Status res = cliInitialize(template, h1, nullInput,
0460: nullOutput, nullOutput, null, currentDir);
0461:
0462: assertEquals("First one executed", 1, h1.cnt);
0463: assertEquals("CLI evaluation failed with return code of h1", 1,
0464: res.getExitCode());
0465:
0466: res = cliInitialize(template, java.util.Collections.EMPTY_LIST,
0467: nullInput, nullOutput, nullOutput, null, currentDir);
0468: assertEquals("But again executed h1", 2, h1.cnt);
0469: assertEquals("Now the result is 2 as cnt++ was increased", 2,
0470: res.getExitCode());
0471:
0472: }
0473:
0474: public void testServerWaitsBeforeFinishInitializationIsCalledOn()
0475: throws Exception {
0476: // this tests will not execute handlers immediatelly
0477: CLIHandler.finishInitialization(true);
0478:
0479: class H extends CLIHandler implements Runnable {
0480: public volatile int cnt;
0481: public volatile int afterFinish = -1;
0482:
0483: public H() {
0484: super (CLIHandler.WHEN_INIT);
0485: }
0486:
0487: protected int cli(Args args) {
0488: cnt++;
0489: LOG.info("Increased cnt to: " + cnt + " by thread "
0490: + Thread.currentThread());
0491: return afterFinish;
0492: }
0493:
0494: public void run() {
0495: // cnt will be two as once the first cliInitialize will
0496: // invoke the handler and once the second cliInitialize
0497: // using the Server
0498: afterFinish = 2;
0499: CLIHandler.finishInitialization(false);
0500: }
0501:
0502: protected void usage(PrintWriter w) {
0503: }
0504: }
0505: H h = new H();
0506:
0507: CLIHandler.Status res = cliInitialize(new String[0], h,
0508: nullInput, nullOutput, nullOutput, null);
0509: assertEquals("Returns 0 as no finishInitialization is called",
0510: 0, res.getExitCode());
0511: // after two seconds it calls finishInitialization
0512: RequestProcessor.Task task = RequestProcessor.getDefault()
0513: .post(h, 7000); // 7s is higher than socket timeout
0514: res = cliInitialize(new String[0], h, nullInput, nullOutput,
0515: nullOutput, null);
0516:
0517: assertEquals(
0518: "Returns 2 as afterFinish needed to be set to 2 before"
0519: + " calling finishInitialization", 2, res
0520: .getExitCode());
0521:
0522: long time = System.currentTimeMillis();
0523: task.waitFinished();
0524: time = System.currentTimeMillis() - time;
0525:
0526: if (time > 1000) {
0527: fail("The waitFinished should return almost immediatelly. But was: "
0528: + time);
0529: }
0530:
0531: if (h.afterFinish != h.cnt) {
0532: // in order to find out whether the failures in issue #44833
0533: // are not caused just by threading issues, let's wait another
0534: // few seconds and print the results of h.afterFinish and h.cnt
0535: // if they will be the same then just replace the initial condition
0536: // by say that h.afterFinish == 2 and h.cnt > 1 is ok
0537: Thread.sleep(5000);
0538: fail("H is not executed before finishInitialization is called :"
0539: + h.afterFinish + " cnt: " + h.cnt);
0540: }
0541:
0542: }
0543:
0544: public void testServerIsNotBlockedByLongRequests() throws Exception {
0545: class H extends CLIHandler {
0546: private int cnt = -1;
0547: public int toReturn;
0548:
0549: public H() {
0550: super (CLIHandler.WHEN_INIT);
0551: }
0552:
0553: protected synchronized int cli(Args args) {
0554: try {
0555: // this simulates really slow, but computing task
0556: Thread.sleep(6555);
0557: } catch (InterruptedException ex) {
0558: throw new IllegalStateException();
0559: }
0560: notifyAll();
0561: cnt++;
0562: return toReturn;
0563: }
0564:
0565: protected void usage(PrintWriter w) {
0566: }
0567: }
0568: H h = new H();
0569:
0570: h.toReturn = 7;
0571: final Integer blockOn = new Integer(99);
0572: CLIHandler.Status res = cliInitialize(new String[0], h,
0573: nullInput, nullOutput, nullOutput, blockOn);
0574: assertEquals("Called once, increased -1 to 0", 0, h.cnt);
0575: assertEquals("Result is provided by H", 7, res.getExitCode());
0576:
0577: // blocks after connection established, before returning the result
0578: class R implements Runnable {
0579: CLIHandler.Status res;
0580:
0581: public void run() {
0582: res = cliInitialize(new String[0],
0583: Collections.EMPTY_LIST, nullInput, nullOutput,
0584: nullOutput, blockOn);
0585: }
0586: }
0587: R r = new R();
0588: RequestProcessor.Task task;
0589: synchronized (h) {
0590: h.toReturn = 5;
0591: task = new org.openide.util.RequestProcessor(
0592: "Blocking request").post(r);
0593: h.wait();
0594: assertEquals("Connects to the h", 1, h.cnt);
0595: if (r.res != null) {
0596: fail("The handler should not be finished, as it blocks in '99' but it is and the result is "
0597: + r.res.getExitCode());
0598: }
0599: }
0600:
0601: // while R is blocked, run another task
0602: h.toReturn = 0;
0603: res = cliInitialize(new String[0], Collections.EMPTY_LIST,
0604: nullInput, nullOutput, nullOutput, null);
0605: assertEquals("Called once, increased to 2", 2, h.cnt);
0606: assertEquals(
0607: "Result is provided by H, H gives 0, changes into -1 right now",
0608: -1, res.getExitCode());
0609:
0610: synchronized (blockOn) {
0611: // let the R task go on
0612: blockOn.notifyAll();
0613: }
0614: task.waitFinished();
0615: assertNotNull("Now it is finished", r.res);
0616: assertEquals(
0617: "Result is -1, if this fails: this usually means that the server is blocked by some work and the task R started new server to handle its request",
0618: 5, r.res.getExitCode());
0619: assertEquals("H called three times (but counting from -1)", 2,
0620: h.cnt);
0621: }
0622:
0623: public void testReadingOfInputWorksInHandler() throws Exception {
0624: final byte[] template = { 1, 2, 3, 4 };
0625:
0626: class H extends CLIHandler {
0627: private byte[] arr;
0628:
0629: public H() {
0630: super (WHEN_INIT);
0631: }
0632:
0633: protected int cli(Args args) {
0634: try {
0635: InputStream is = args.getInputStream();
0636: arr = new byte[is.available() / 2];
0637: if (arr.length > 0) {
0638: assertEquals("Read amount is the same",
0639: arr.length, is.read(arr));
0640: }
0641: is.close();
0642: } catch (IOException ex) {
0643: fail("There is an exception: " + ex);
0644: }
0645: return 0;
0646: }
0647:
0648: protected void usage(PrintWriter w) {
0649: }
0650: }
0651: H h1 = new H();
0652: H h2 = new H();
0653:
0654: // why twice? first attempt is direct, second thru the socket server
0655: for (int i = 0; i < 2; i++) {
0656: CLIHandler.Status res = cliInitialize(new String[0],
0657: new H[] { h1, h2 }, new ByteArrayInputStream(
0658: template), nullOutput, nullOutput);
0659:
0660: assertNotNull("Attempt " + i + ": " + "Can be read", h1.arr);
0661: assertEquals("Attempt " + i + ": " + "Read two bytes", 2,
0662: h1.arr.length);
0663: assertEquals("Attempt " + i + ": " + "First is same",
0664: template[0], h1.arr[0]);
0665: assertEquals("Attempt " + i + ": " + "Second is same",
0666: template[1], h1.arr[1]);
0667:
0668: assertNotNull("Attempt " + i + ": " + "Can read as well",
0669: h2.arr);
0670: assertEquals("Attempt " + i + ": " + "Just one char", 1,
0671: h2.arr.length);
0672: assertEquals(
0673: "Attempt " + i + ": " + "And is the right one",
0674: template[2], h2.arr[0]);
0675:
0676: h1.arr = null;
0677: h2.arr = null;
0678: }
0679: }
0680:
0681: public void testReadingMoreThanAvailableIsOk() throws Exception {
0682: final byte[] template = { 1, 2, 3, 4 };
0683:
0684: class H extends CLIHandler {
0685: private byte[] arr;
0686:
0687: public H() {
0688: super (WHEN_INIT);
0689: }
0690:
0691: protected int cli(Args args) {
0692: try {
0693: InputStream is = args.getInputStream();
0694: arr = new byte[8];
0695: assertEquals(
0696: "Read amount is the maximum of template",
0697: template.length, is.read(arr));
0698: is.close();
0699: } catch (IOException ex) {
0700: fail("There is an exception: " + ex);
0701: }
0702: return 0;
0703: }
0704:
0705: protected void usage(PrintWriter w) {
0706: }
0707: }
0708: H h1 = new H();
0709:
0710: // why twice? first attempt is direct, second thru the socket server
0711: for (int i = 0; i < 2; i++) {
0712: CLIHandler.Status res = cliInitialize(new String[0],
0713: new H[] { h1 }, new ByteArrayInputStream(template),
0714: nullOutput, nullOutput);
0715:
0716: assertNotNull("Attempt " + i + ": " + "Can be read", h1.arr);
0717: assertEquals("Attempt " + i + ": " + "First is same",
0718: template[0], h1.arr[0]);
0719: assertEquals("Attempt " + i + ": " + "Second is same",
0720: template[1], h1.arr[1]);
0721: assertEquals("Attempt " + i + ": " + "3rd is same",
0722: template[2], h1.arr[2]);
0723: assertEquals("Attempt " + i + ": " + "4th is same",
0724: template[3], h1.arr[3]);
0725:
0726: h1.arr = null;
0727: }
0728: }
0729:
0730: public void testWritingToOutputIsFine() throws Exception {
0731: final byte[] template = { 1, 2, 3, 4 };
0732:
0733: class H extends CLIHandler {
0734: public H() {
0735: super (WHEN_INIT);
0736: }
0737:
0738: protected int cli(Args args) {
0739: try {
0740: OutputStream os = args.getOutputStream();
0741: os.write(template);
0742: os.close();
0743:
0744: os = args.getErrorStream();
0745: os.write(0);
0746: os.write(1);
0747: os.write(2);
0748: os.write(3);
0749: os.write(4);
0750: os.close();
0751: } catch (IOException ex) {
0752: fail("There is an exception: " + ex);
0753: }
0754: return 0;
0755: }
0756:
0757: protected void usage(PrintWriter w) {
0758: }
0759: }
0760: H h1 = new H();
0761: H h2 = new H();
0762:
0763: // why twice? first attempt is direct, second thru the socket server
0764: for (int i = 0; i < 2; i++) {
0765: ByteArrayOutputStream os = new ByteArrayOutputStream();
0766: ByteArrayOutputStream err = new ByteArrayOutputStream();
0767:
0768: CLIHandler.Status res = cliInitialize(new String[0],
0769: new H[] { h1, h2 }, nullInput, os, err);
0770:
0771: byte[] arr = os.toByteArray();
0772: assertEquals("Double size of template",
0773: template.length * 2, arr.length);
0774:
0775: for (int pos = 0; pos < arr.length; pos++) {
0776: assertEquals(pos + ". is the same", template[pos
0777: % template.length], arr[pos]);
0778: }
0779:
0780: byte[] errArr = err.toByteArray();
0781: assertEquals("5 bytes", 10, errArr.length);
0782: for (int x = 0; x < errArr.length; x++) {
0783: assertEquals(errArr[x], x % 5);
0784: }
0785: }
0786: }
0787:
0788: public void testGetInetAddressDoesNotBlock() throws Exception {
0789: CLIHandler.Status res = cliInitialize(new String[0],
0790: Collections.EMPTY_LIST, nullInput, nullOutput,
0791: nullOutput, Integer.valueOf(27));
0792: assertEquals("CLIHandler init finished", 0, res.getExitCode());
0793: }
0794:
0795: public void testServerCanBeStopped() throws Exception {
0796: class H extends CLIHandler {
0797: private int cnt = -1;
0798: public int toReturn;
0799:
0800: public H() {
0801: super (CLIHandler.WHEN_INIT);
0802: }
0803:
0804: protected synchronized int cli(Args args) {
0805: notifyAll();
0806: cnt++;
0807: return toReturn;
0808: }
0809:
0810: protected void usage(PrintWriter w) {
0811: }
0812: }
0813: H h = new H();
0814:
0815: h.toReturn = 7;
0816: CLIHandler.Status res = cliInitialize(new String[0], h,
0817: nullInput, nullOutput, nullOutput, null);
0818: assertEquals("Called once, increased -1 to 0", 0, h.cnt);
0819: assertEquals("Result is provided by H", 7, res.getExitCode());
0820:
0821: CLIHandler.stopServer();
0822:
0823: h.toReturn = 5;
0824: h.cnt = -1;
0825: res = cliInitialize(new String[0], Collections.EMPTY_LIST,
0826: nullInput, nullOutput, nullOutput, null);
0827: assertEquals("Not called -1", -1, h.cnt);
0828: // right now the handler will not be called, if there is anything else
0829: // to do, let's wait for such requirements
0830: }
0831:
0832: public void testHostNotFound64004() throws Exception {
0833: class H extends CLIHandler {
0834: private int cnt;
0835: public int toReturn;
0836:
0837: public H() {
0838: super (CLIHandler.WHEN_INIT);
0839: }
0840:
0841: protected synchronized int cli(Args args) {
0842: notifyAll();
0843: cnt++;
0844: return toReturn;
0845: }
0846:
0847: protected void usage(PrintWriter w) {
0848: }
0849: }
0850: H h = new H();
0851:
0852: // handlers shall not be executed immediatelly
0853: CLIHandler.finishInitialization(true);
0854:
0855: h.toReturn = 7;
0856: CLIHandler.Status res = cliInitialize(new String[0], h,
0857: nullInput, nullOutput, nullOutput, new Integer(667));
0858: // finish all calls
0859: int newRes = CLIHandler.finishInitialization(false);
0860:
0861: assertEquals("Called once, increased", 1, h.cnt);
0862: assertEquals("Result is provided by H", 7, newRes);
0863: }
0864:
0865: //
0866: // Utility methods
0867: //
0868:
0869: private static CLIHandler.Status cliInitialize(String[] args,
0870: CLIHandler handler, InputStream is, OutputStream os,
0871: OutputStream err, Integer lock) {
0872: return cliInitialize(args, handler, is, os, err, lock, System
0873: .getProperty("user.dir"));
0874: }
0875:
0876: private static CLIHandler.Status cliInitialize(String[] args,
0877: CLIHandler handler, InputStream is, OutputStream os,
0878: OutputStream err, Integer lock, String currentDir) {
0879: return cliInitialize(args, Collections.nCopies(1, handler), is,
0880: os, err, lock, currentDir);
0881: }
0882:
0883: private static CLIHandler.Status cliInitialize(String[] args,
0884: CLIHandler[] arr, InputStream is, OutputStream os,
0885: OutputStream err) {
0886: return cliInitialize(args, Arrays.asList(arr), is, os, err,
0887: null);
0888: }
0889:
0890: private static CLIHandler.Status cliInitialize(String[] args,
0891: List coll, InputStream is, OutputStream os,
0892: java.io.OutputStream err, Integer lock) {
0893: return cliInitialize(args, coll, is, os, err, lock, System
0894: .getProperty("user.dir"));
0895: }
0896:
0897: private static CLIHandler.Status cliInitialize(String[] args,
0898: List coll, InputStream is, OutputStream os,
0899: java.io.OutputStream err, Integer lock, String currentDir) {
0900: return CLIHandler.initialize(new CLIHandler.Args(args, is, os,
0901: err, currentDir), lock, coll, false, true, null);
0902: }
0903:
0904: private static final class InitializeRunner extends Object
0905: implements Runnable {
0906: private Integer block;
0907: private String[] args;
0908: private CLIHandler handler;
0909: private CLIHandler.Status result;
0910: private boolean noEnd;
0911:
0912: public InitializeRunner(int till) throws InterruptedException {
0913: this (new String[0], null, till);
0914: }
0915:
0916: public InitializeRunner(int till, boolean noEnd)
0917: throws InterruptedException {
0918: this (new String[0], null, till, noEnd);
0919: }
0920:
0921: public InitializeRunner(Integer till, boolean noEnd)
0922: throws InterruptedException {
0923: this (new String[0], null, till, noEnd);
0924: }
0925:
0926: public InitializeRunner(String[] args, CLIHandler h, int till)
0927: throws InterruptedException {
0928: this (args, h, new Integer(till));
0929: }
0930:
0931: public InitializeRunner(String[] args, CLIHandler h,
0932: Integer till) throws InterruptedException {
0933: this (args, h, till, false);
0934: }
0935:
0936: private InitializeRunner(String[] args, CLIHandler h,
0937: Integer till, boolean noEnd)
0938: throws InterruptedException {
0939: this .args = args;
0940: this .block = till;
0941: this .handler = h;
0942: this .noEnd = noEnd;
0943:
0944: synchronized (block) {
0945: new RequestProcessor("InitializeRunner blocks on "
0946: + till).post(this );
0947: block.wait();
0948: }
0949: }
0950:
0951: public void run() {
0952: synchronized (block) {
0953: result = CLIHandler
0954: .initialize(
0955: new CLIHandler.Args(args, nullInput,
0956: nullOutput, nullOutput, ""),
0957: block,
0958: handler == null ? java.util.Collections.EMPTY_LIST
0959: : java.util.Collections
0960: .nCopies(1, handler),
0961: false, true, null);
0962: if (!noEnd) {
0963: // we are finished, wake up guys in next() if any
0964: block.notifyAll();
0965: }
0966: }
0967: synchronized (this ) {
0968: notifyAll();
0969: }
0970: }
0971:
0972: /** Executes the code to next invocation */
0973: public void next() throws InterruptedException {
0974: synchronized (block) {
0975: block.notify();
0976: block.wait();
0977: }
0978: }
0979:
0980: /** Has already the resutl?
0981: */
0982: public boolean hasResult() {
0983: return result != null;
0984: }
0985:
0986: public boolean waitResult() throws InterruptedException {
0987: synchronized (this ) {
0988: for (int i = 0; i < 10; i++) {
0989: if (result != null) {
0990: return true;
0991: }
0992: wait(1000);
0993: }
0994: }
0995: fail("No result produced: " + result);
0996: return true;
0997: }
0998:
0999: /** Gets the resultFile, if there is some,
1000: */
1001: public File resultFile() {
1002: if (result == null) {
1003: fail("No result produced");
1004: }
1005: return result.getLockFile();
1006: }
1007:
1008: /** Gets the port, if there is some,
1009: */
1010: public int resultPort() {
1011: if (result == null) {
1012: fail("No result produced");
1013: }
1014: return result.getServerPort();
1015: }
1016: } // end of InitializeRunner
1017:
1018: }
|