|
What this is
Other links
The source code/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun * Microsystems, Inc. All Rights Reserved. */ package org.netbeans; import java.io.*; import junit.textui.TestRunner; import org.netbeans.junit.*; import java.util.*; import junit.framework.AssertionFailedError; import org.openide.util.RequestProcessor; /** * Test the command-line-interface handler. * @author Jaroslav Tulach */ public class CLIHandlerTest extends NbTestCase { private static ByteArrayInputStream nullInput = new ByteArrayInputStream(new byte[0]); private static ByteArrayOutputStream nullOutput = new ByteArrayOutputStream(); private StringBuffer sb; public CLIHandlerTest(String name) { super(name); } public static void main(String[] args) { TestRunner.run(new NbTestSuite(CLIHandlerTest.class)); } protected void setUp() throws Exception { super.setUp(); // all handlers shall be executed immediatelly CLIHandler.finishInitialization (false); // setups a temporary file String tmp = System.getProperty("java.io.tmpdir"); assertNotNull(tmp); System.getProperties().put("netbeans.user", tmp); File f = new File(tmp, "lock"); if (f.exists()) { assertTrue("Clean up previous mess", f.delete()); assertTrue(!f.exists()); } } protected void runTest () throws Throwable { sb = new StringBuffer (); CLIHandler.registerDebug (sb); try { super.runTest (); } catch (AssertionFailedError ex) { AssertionFailedError ne = new AssertionFailedError ("Failed as " + ex.getMessage () + " with text:\n" + sb.toString ()); ne.setStackTrace (ex.getStackTrace ()); throw ne; } finally { // clean the debug CLIHandler.registerDebug (null); } } public void testFileExistsButItCannotBeRead() throws Exception { // just creates the file and blocks InitializeRunner runner = new InitializeRunner(10); // blocks when operation fails InitializeRunner second = new InitializeRunner(85); for (int i = 0; i < 3; i++) { second.next(); } // finishes the code runner.next(); assertNotNull("Runner succeeded to allocate the file", runner.resultFile()); // let the second code go on as well second.next(); assertEquals("The same file has been allocated", runner.resultFile(), second.resultFile()); } public void testFileExistsButTheServerCannotBeContacted() throws Exception { // start the server and block InitializeRunner runner = new InitializeRunner(65); assertNotNull("File created", runner.resultFile()); assertTrue("Port allocated", runner.resultPort() != 0); // blocks when operation fails InitializeRunner second = new InitializeRunner(85); // second try should be ok second.next(); assertNotNull("Previous file deleted and new one created", second.resultFile()); assertTrue("Another port allocated", second.resultPort() != runner.resultPort()); } public void testFileExistsButTheServerCannotBeContactedAndWeDoNotWantToCleanTheFile() throws Exception { // start the server and block InitializeRunner runner = new InitializeRunner(65); assertNotNull("File created", runner.resultFile()); assertTrue("Port allocated", runner.resultPort() != 0); CLIHandler.Status res = CLIHandler.initialize( new CLIHandler.Args(new String[0], nullInput, nullOutput, ""), null, Collections.EMPTY_LIST, false, false, null ); assertEquals ("Cannot connect", CLIHandler.Status.CANNOT_CONNECT, res.getExitCode()); } public void testFileExistsButTheKeyIsNotRecognized() throws Exception { // start the server be notified when it accepts connection InitializeRunner runner = new InitializeRunner(65); assertNotNull("File created", runner.resultFile()); assertTrue("Port allocated", runner.resultPort() != 0); int s = (int)runner.resultFile().length(); byte[] copy = new byte[s]; FileInputStream is = new FileInputStream(runner.resultFile()); assertEquals("Read fully", s, is.read(copy)); is.close(); // change the key copy[s - 1]++; FileOutputStream os = new FileOutputStream(runner.resultFile()); os.write(copy); os.close(); // try to connect to previous server be notified as soon as it // sends request InitializeRunner second = new InitializeRunner(30); // handle the request, say NO runner.next(); // read the reply and allocate new port second.next(); assertNotNull("Previous file deleted and new one created", second.resultFile()); assertTrue("Another port allocated", second.resultPort() != runner.resultPort()); } public void testCLIHandlersCanChangeLocationOfLockFile() throws Exception { File f = File.createTempFile("suffix", "tmp").getParentFile(); final File dir = new File(f, "subdir"); dir.delete(); assertTrue(dir.exists() || dir.mkdir()); class UserDir extends CLIHandler { private int cnt; public UserDir() { super(WHEN_BOOT); } protected int cli(Args args) { cnt++; System.setProperty("netbeans.user", dir.toString()); return 0; } protected void usage(PrintWriter w) {} } UserDir ud = new UserDir(); CLIHandler.Status res = cliInitialize(new String[0], ud, nullInput, nullOutput, null); assertEquals("Our command line handler is called once", 1, ud.cnt); assertEquals("Lock file is created in dir", dir, res.getLockFile().getParentFile()); dir.delete(); } public void testCLIHandlerCanStopEvaluation() throws Exception { class H extends CLIHandler { private int cnt; public H() { super(WHEN_INIT); } protected int cli(Args args) { cnt++; return 1; } protected void usage(PrintWriter w) {} } H h1 = new H(); H h2 = new H(); CLIHandler.Status res = cliInitialize(new String[0], new H[] { h1, h2 }, nullInput, nullOutput); assertEquals("CLI evaluation failed with return code of h1", 1, res.getExitCode()); assertEquals("First one executed", 1, h1.cnt); assertEquals("Not the second one", 0, h2.cnt); } public void testWhenInvokedTwiceParamsGoToTheFirstHandler() throws Exception { final String[] template = { "Ahoj", "Hello" }; final String currentDir = "MyDir"; class H extends CLIHandler { private int cnt; public H() { super(WHEN_INIT); } protected int cli(Args args) { String[] a = args.getArguments(); String[] t = template; assertEquals("Same length", t.length, a.length); assertEquals("First is same", t[0], a[0]); assertEquals("Second is same", t[1], a[1]); assertEquals("Current dir is fine", currentDir, args.getCurrentDirectory().toString()); return ++cnt; } protected void usage(PrintWriter w) {} } H h1 = new H(); CLIHandler.Status res = cliInitialize(template, h1, nullInput, nullOutput, null, currentDir); assertEquals("First one executed", 1, h1.cnt); assertEquals("CLI evaluation failed with return code of h1", 1, res.getExitCode()); res = cliInitialize(template, java.util.Collections.EMPTY_LIST, nullInput, nullOutput, null, currentDir); assertEquals("But again executed h1", 2, h1.cnt); assertEquals("Now the result is 2 as cnt++ was increased", 2, res.getExitCode()); } public void testServerWaitsBeforeFinishInitializationIsCalledOn () throws Exception { // this tests will not execute handlers immediatelly CLIHandler.finishInitialization (true); class H extends CLIHandler implements Runnable { public volatile int cnt; public volatile int afterFinish = -1; public H () { super (CLIHandler.WHEN_INIT); } protected int cli (Args args) { cnt++; sb.append ("Increased cnt to: "); sb.append (cnt); sb.append (" by thread "); sb.append (Thread.currentThread ()); return afterFinish; } public void run () { // cnt will be two as once the first cliInitialize will // invoke the handler and once the second cliInitialize // using the Server afterFinish = 2; CLIHandler.finishInitialization (false); } protected void usage (PrintWriter w) {} } H h = new H (); CLIHandler.Status res = cliInitialize (new String[0], h, nullInput, nullOutput, null); assertEquals ("Returns 0 as no finishInitialization is called", 0, res.getExitCode ()); // after two seconds it calls finishInitialization RequestProcessor.Task task = RequestProcessor.getDefault ().post (h, 7000); // 7s is higher than socket timeout res = cliInitialize (new String[0], h, nullInput, nullOutput, null); assertEquals ("Returns 2 as afterFinish needed to be set to 2 before" + " calling finishInitialization", 2, res.getExitCode ()); long time = System.currentTimeMillis (); task.waitFinished (); time = System.currentTimeMillis () - time; if (time > 1000) { fail ("The waitFinished should return almost immediatelly. But was: " + time); } if (h.afterFinish != h.cnt) { // in order to find out whether the failures in issue #44833 // are not caused just by threading issues, let's wait another // few seconds and print the results of h.afterFinish and h.cnt // if they will be the same then just replace the initial condition // by say that h.afterFinish == 2 and h.cnt > 1 is ok Thread.sleep (5000); fail ("H is not executed before finishInitialization is called :" + h.afterFinish + " cnt: " + h.cnt); } } public void testServerIsNotBlockedByLongRequests() throws Exception { class H extends CLIHandler { private int cnt = -1; public int toReturn; public H() { super(CLIHandler.WHEN_INIT); } protected synchronized int cli(Args args) { try { // this simulates really slow, but computing task Thread.sleep (6555); } catch (InterruptedException ex) { throw new IllegalStateException (); } notifyAll(); cnt++; return toReturn; } protected void usage(PrintWriter w) {} } H h = new H(); h.toReturn = 7; final Integer blockOn = new Integer(99); CLIHandler.Status res = cliInitialize(new String[0], h, nullInput, nullOutput, blockOn); assertEquals("Called once, increased -1 to 0", 0, h.cnt); assertEquals("Result is provided by H", 7, res.getExitCode()); // blocks after connection established, before returning the result class R implements Runnable { CLIHandler.Status res; public void run() { res = cliInitialize(new String[0], Collections.EMPTY_LIST, nullInput, nullOutput, blockOn); } } R r = new R(); RequestProcessor.Task task; synchronized (h) { h.toReturn = 5; task = new org.openide.util.RequestProcessor("Blocking request").post(r); h.wait(); assertEquals("Connects to the h", 1, h.cnt); if (r.res != null) { fail ("The handler should not be finished, as it blocks in '99' but it is and the result is " + r.res.getExitCode ()); } } // while R is blocked, run another task h.toReturn = 0; res = cliInitialize(new String[0], Collections.EMPTY_LIST, nullInput, nullOutput, null); assertEquals("Called once, increased to 2", 2, h.cnt); assertEquals("Result is provided by H, H gives 0, changes into -1 right now", -1, res.getExitCode()); synchronized (blockOn) { // let the R task go on blockOn.notifyAll(); } task.waitFinished(); assertNotNull("Now it is finished", r.res); assertEquals("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", 5, r.res.getExitCode()); assertEquals("H called three times (but counting from -1)", 2, h.cnt); } public void testReadingOfInputWorksInHandler() throws Exception { final byte[] template = { 1, 2, 3, 4 }; class H extends CLIHandler { private byte[] arr; public H() { super(WHEN_INIT); } protected int cli(Args args) { try { InputStream is = args.getInputStream(); arr = new byte[is.available() / 2]; if (arr.length > 0) { assertEquals("Read amount is the same", arr.length, is.read(arr)); } is.close(); } catch (IOException ex) { fail("There is an exception: " + ex); } return 0; } protected void usage(PrintWriter w) {} } H h1 = new H(); H h2 = new H(); // why twice? first attempt is direct, second thru the socket server for (int i = 0; i < 2; i++) { CLIHandler.Status res = cliInitialize( new String[0], new H[] { h1, h2 }, new ByteArrayInputStream(template), nullOutput); assertNotNull("Attempt " + i + ": " + "Can be read", h1.arr); assertEquals("Attempt " + i + ": " + "Read two bytes", 2, h1.arr.length); assertEquals("Attempt " + i + ": " + "First is same", template[0], h1.arr[0]); assertEquals("Attempt " + i + ": " + "Second is same", template[1], h1.arr[1]); assertNotNull("Attempt " + i + ": " + "Can read as well", h2.arr); assertEquals("Attempt " + i + ": " + "Just one char", 1, h2.arr.length); assertEquals("Attempt " + i + ": " + "And is the right one", template[2], h2.arr[0]); h1.arr = null; h2.arr = null; } } public void testReadingMoreThanAvailableIsOk () throws Exception { final byte[] template = { 1, 2, 3, 4 }; class H extends CLIHandler { private byte[] arr; public H() { super(WHEN_INIT); } protected int cli(Args args) { try { InputStream is = args.getInputStream(); arr = new byte[8]; assertEquals("Read amount is the maximum of template", template.length, is.read(arr)); is.close(); } catch (IOException ex) { fail("There is an exception: " + ex); } return 0; } protected void usage(PrintWriter w) {} } H h1 = new H(); // why twice? first attempt is direct, second thru the socket server for (int i = 0; i < 2; i++) { CLIHandler.Status res = cliInitialize( new String[0], new H[] { h1 }, new ByteArrayInputStream(template), nullOutput); assertNotNull("Attempt " + i + ": " + "Can be read", h1.arr); assertEquals("Attempt " + i + ": " + "First is same", template[0], h1.arr[0]); assertEquals("Attempt " + i + ": " + "Second is same", template[1], h1.arr[1]); assertEquals("Attempt " + i + ": " + "3rd is same", template[2], h1.arr[2]); assertEquals("Attempt " + i + ": " + "4th is same", template[3], h1.arr[3]); h1.arr = null; } } public void testWritingToOutputIsFine() throws Exception { final byte[] template = { 1, 2, 3, 4 }; class H extends CLIHandler { public H() { super(WHEN_INIT); } protected int cli(Args args) { try { OutputStream os = args.getOutputStream(); os.write(template); os.close(); } catch (IOException ex) { fail("There is an exception: " + ex); } return 0; } protected void usage(PrintWriter w) {} } H h1 = new H(); H h2 = new H(); // why twice? first attempt is direct, second thru the socket server for (int i = 0; i < 2; i++) { ByteArrayOutputStream os = new ByteArrayOutputStream(); CLIHandler.Status res = cliInitialize( new String[0], new H[] { h1, h2 }, nullInput, os); byte[] arr = os.toByteArray(); assertEquals("Double size of template", template.length * 2, arr.length); for (int pos = 0; pos < arr.length; pos++) { assertEquals(pos + ". is the same", template[pos % template.length], arr[pos]); } } } // // Utility methods // private static CLIHandler.Status cliInitialize(String[] args, CLIHandler handler, InputStream is, OutputStream os, Integer lock) { return cliInitialize(args, handler, is, os, lock, System.getProperty ("user.dir")); } private static CLIHandler.Status cliInitialize(String[] args, CLIHandler handler, InputStream is, OutputStream os, Integer lock, String currentDir) { return cliInitialize(args, Collections.nCopies(1, handler), is, os, lock, currentDir); } private static CLIHandler.Status cliInitialize(String[] args, CLIHandler[] arr, InputStream is, OutputStream os) { return cliInitialize(args, Arrays.asList(arr), is, os, null); } private static CLIHandler.Status cliInitialize(String[] args, List coll, InputStream is, OutputStream os, Integer lock) { return cliInitialize (args, coll, is, os, lock, System.getProperty ("user.dir")); } private static CLIHandler.Status cliInitialize(String[] args, List coll, InputStream is, OutputStream os, Integer lock, String currentDir) { return CLIHandler.initialize(new CLIHandler.Args(args, is, os, currentDir), lock, coll, false, true, null); } private static final class InitializeRunner extends Object implements Runnable { private Integer block; private String[] args; private CLIHandler handler; private CLIHandler.Status result; public InitializeRunner(int till) throws InterruptedException { this(new String[0], null, till); } public InitializeRunner(String[] args, CLIHandler h, int till) throws InterruptedException { this(args, h, new Integer(till)); } public InitializeRunner(String[] args, CLIHandler h, Integer till) throws InterruptedException { this.args = args; this.block = till; this.handler = h; synchronized (block) { RequestProcessor.getDefault().post(this); block.wait(); } } public void run() { synchronized (block) { result = CLIHandler.initialize( new CLIHandler.Args(args, nullInput, nullOutput, ""), block, handler == null ? java.util.Collections.EMPTY_LIST : java.util.Collections.nCopies(1, handler), false, true, null ); // we are finished, wake up guys in next() if any block.notifyAll(); } } /** Executes the code to next invocation */ public void next() throws InterruptedException { synchronized (block) { block.notify(); block.wait(); } } /** Has already the resutl? */ public boolean hasResult() { return result != null; } /** Gets the resultFile, if there is some, */ public File resultFile() { if (result == null) { fail("No result produced"); } return result.getLockFile(); } /** Gets the port, if there is some, */ public int resultPort() { if (result == null) { fail("No result produced"); } return result.getServerPort(); } } // end of InitializeRunner } |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.