/******************************************************************************* * Copyright (c) 2000, 2015 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jdt.debug.tests.core; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import org.eclipse.core.resources.IContainer; import org.eclipse.core.runtime.CoreException; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfigurationType; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.debug.core.ILaunchManager; import org.eclipse.debug.core.model.IProcess; import org.eclipse.debug.ui.console.IConsole; import org.eclipse.debug.ui.console.IConsoleLineTrackerExtension; import org.eclipse.jdt.debug.testplugin.ConsoleLineTracker; import org.eclipse.jdt.debug.tests.AbstractDebugTest; import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; import org.eclipse.jdt.launching.IVMInstall; import org.eclipse.jdt.launching.JavaRuntime; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; /** * Tests for program and VM arguments */ public class ArgumentTests extends AbstractDebugTest { private Object fLock = new Object(); private class ConsoleArgumentOutputRetriever implements IConsoleLineTrackerExtension { StringBuffer buffer; IDocument document; boolean closed = false; /** * @see org.eclipse.debug.ui.console.IConsoleLineTracker#dispose() */ @Override public void dispose() {} /** * @see org.eclipse.debug.ui.console.IConsoleLineTracker#init(org.eclipse.debug.ui.console.IConsole) */ @Override public void init(IConsole console) { buffer = new StringBuffer(); document = console.getDocument(); } /** * @see org.eclipse.debug.ui.console.IConsoleLineTracker#lineAppended(org.eclipse.jface.text.IRegion) */ @Override public void lineAppended(IRegion line) { try { assertNotNull("received notification of invalid line", line); assertNotNull("buffer is null", buffer); buffer.append(document.get(line.getOffset(), line.getLength())); } catch (BadLocationException e) { e.printStackTrace(); } } /** * @see org.eclipse.debug.ui.console.IConsoleLineTrackerExtension#consoleClosed() */ @Override public void consoleClosed() { synchronized (fLock) { closed = true; fLock.notifyAll(); } } /** * @return the output */ public String getOutput() { // wait to be closed synchronized (fLock) { if (!closed) { try { fLock.wait(DEFAULT_TIMEOUT); } catch (InterruptedException e) { } } } if (!closed) { // output contents to console in case of error if (buffer != null) { System.out.println(); System.out.println(ArgumentTests.this.getName()); System.out.println("\treceived " + buffer.length() + " chars: " + buffer.toString()); } } assertNotNull("Line tracker did not receive init notification", buffer); assertTrue("Line tracker did not receive close notification", closed); return buffer.toString(); } } /** * Constructor * @param name the name of the test */ public ArgumentTests(String name) { super(name); } /** * Creates and returns a new launch config the given name */ protected ILaunchConfigurationWorkingCopy newConfiguration(IContainer container, String name) throws CoreException { ILaunchConfigurationType type = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION); return type.newInstance(container, name); } /* * VM argument tests */ /** * Test a single VM argument. * Program output should be: foo * @throws CoreException */ public void testVMArgSingle() throws CoreException { testWithVMArg("-Dfoo=foo", "foo"); } /** * Test a VM argument with quotes in a valid location. * Program output should be: foo * @throws CoreException */ public void testVMArgSimpleQuotes() throws CoreException { testWithVMArg("-Dfoo=\"foo\"", "foo"); } /** * Test a VM argument with the standard style quoting for arguments with * spaces. * Program output should be: foo bar * @throws CoreException */ public void testVMArgStandardQuotes() throws CoreException { testWithVMArg("-Dfoo=\"foo bar\"", "foo bar"); } /** * Test a VM argument with quotes in a standard location. * Program output should be: "foo" * @throws CoreException */ public void testVMArgStandardEmbeddedQuotes() throws CoreException { testWithVMArg("-Dfoo=\"\\\"foo\\\"\"", "\"foo\""); } /** * Test a VM argument with the quoting style we recommended as a workaround * to a bug (now fixed) that we suggested in the past. * Program output should be: foo bar * @throws CoreException */ public void testVMArgWorkaroundQuotes() throws CoreException { testWithVMArg("\"-Dfoo=foo bar\"", "foo bar"); } /** * Test a VM argument with quotes placed in a creative (non-standard, but * valid) location * Program output should be: foo bar * @throws CoreException */ public void testVMArgCreativeQuotes() throws CoreException { testWithVMArg("-Dfoo=fo\"o b\"ar", "foo bar"); } /** * Test a VM argument with embedded quotes. * Program output should be: "foo bar" * @throws CoreException */ public void testVMArgEmbeddedQuotes() throws CoreException { testWithVMArg("-Dfoo=\"\\\"foo bar\\\"\"", "\"foo bar\""); } /** * Test a VM argument with quotes placed in a creative (non-standard, but * valid) location * Program output should be: fo"o b"ar * @throws CoreException */ public void testVMArgEmbeddedCreativeQuotes() throws CoreException { testWithVMArg("-Dfoo=fo\"\\\"o b\\\"\"ar", "fo\"o b\"ar"); } /* * Program argument tests */ /** * Test a single program argument. * Program output should be: foo * @throws CoreException */ public void testProgramArgSingle() throws CoreException { testWithProgramArg("foo", "foo"); } /** * Test multiple program arguments. * Program output should be: foo\nbar * @throws CoreException */ public void testProgramArgMultiple() throws CoreException { testWithProgramArg("foo bar", "foobar"); } /** * Test a program argument with quotes in a valid location. * Program output should be: foo * @throws CoreException */ public void testProgramArgSimpleQuotes() throws CoreException { testWithProgramArg("\"foo\"", "foo"); } /** * Test a program argument with quotes in a standard location. * Program output should be: foo bar * @throws CoreException */ public void testProgramArgStandardQuotes() throws CoreException { testWithProgramArg("\"foo bar\"", "foo bar"); } /** * Test a program argument with quotes placed in a creative (non-standard, * but valid) location. * Program output should be: foo bar * @throws CoreException */ public void testProgramArgCreativeQuotes() throws CoreException { testWithProgramArg("fo\"o b\"ar", "foo bar"); } /** * Test a program argument with embedded quotes in a standard location. * Program output should be: "blah" * @throws CoreException */ public void testProgramArgEmbeddedQuotes() throws CoreException { testWithProgramArg("\\\"blah\\\"", "\"blah\""); } /** * Test a program argument with embedded quotes in a creative (non-standard, * but valie) location. * Program output should be: f"o"o * @throws CoreException */ public void testProgramArgCreativeEmbeddedQuotes() throws CoreException { testWithProgramArg("f\\\"o\\\"o", "f\"o\"o"); } /** * Test a program argument with one empty string * * Program output should be: 1 * @throws CoreException */ public void testProgramArgEmptyString() throws CoreException { testProgramArgCount("\"\"", "1"); // assert that it's really the empty string: testWithProgramArg("\"\"", ""); } /** * Test a program with an empty string among other args. * * Program output should be: 4 * @throws CoreException */ public void testProgramArgEmptyStringWithOthers() throws CoreException { testProgramArgCount("word1 \"\" \"part1 part2\" word2", "4"); } /** * Test a program argument with one double quote. We should pass in the * empty string to match Java console behavior. * * Program output should be: 1 * @throws CoreException */ public void testProgramArgOneQuote() throws CoreException { testProgramArgCount("\"", "1"); } /** * Runs the FooPropertyPrinter with the given VM arguments and checks for * the given output. * @param argString the VM arguments * @param argValue the expected output */ private void testWithVMArg(String argString, String outputValue) throws CoreException { testOutput("FooPropertyPrinter", argString, null, outputValue); } /** * Runs the ArgumentPrinter with the given program arguments * @param argString * @param outputValue * @throws CoreException */ private void testWithProgramArg(String argString, String outputValue) throws CoreException { testOutput("ArgumentPrinter", null, argString, outputValue); } /** * Runs the ArgumentCounter with the given program arguments * @param argString * @param outputValue * @throws CoreException */ private void testProgramArgCount(String argString, String outputValue) throws CoreException { testOutput("ArgumentCounter", null, argString, outputValue); } /** * Runs the given program with the given VM arguments and the given program arguments and * asserts that the output matches the given output. * @param mainTypeName the type to execute * @param vmArgs the VM arguments to specify * @param programArgs the program arguments to specify * @param outputValue the expected output */ private void testOutput(String mainTypeName, String vmArgs, String programArgs, String outputValue) throws CoreException { ILaunchConfigurationWorkingCopy workingCopy = newConfiguration(null, "config1"); workingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, get14Project().getProject().getName()); workingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, mainTypeName); workingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_STOP_IN_MAIN, true); workingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, vmArgs); workingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS, programArgs); IVMInstall vm = JavaRuntime.getVMInstall(get14Project()); assertNotNull("shold be able to get the default VM install from the 1.4 project", vm); //workingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_JRE_CONTAINER_PATH, JavaRuntime.newJREContainerPath(vm).toPortableString()); // use 'java' instead of 'javaw' to launch tests (javaw is problematic on JDK1.4.2) Map<String, String> map = new HashMap<String, String>(1); map.put(IJavaLaunchConfigurationConstants.ATTR_JAVA_COMMAND, "java"); workingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL_TYPE_SPECIFIC_ATTRS_MAP, map); ConsoleArgumentOutputRetriever retriever = new ConsoleArgumentOutputRetriever(); ConsoleLineTracker.setDelegate(retriever); IProcess process = null; ILaunch launch = null; try { HashSet<String> set = new HashSet<String>(); set.add(ILaunchManager.RUN_MODE); ensurePreferredDelegate(workingCopy, set); launch = workingCopy.launch(ILaunchManager.RUN_MODE, null); process = launch.getProcesses()[0]; } catch (Exception e) { e.printStackTrace(); } try { String output = retriever.getOutput(); // output if in error if (!outputValue.equals(output)) { System.out.println(); System.out.println(getName()); System.out.println("\tExpected: " + outputValue); System.out.println("\tActual: " + output); } assertEquals(outputValue, output); } finally { ConsoleLineTracker.setDelegate(null); if (process != null) { process.terminate(); } if (launch != null) { getLaunchManager().removeLaunch(launch); } } } /** * Tests the default VM args * @throws CoreException */ /*public void testDefaultVMArgs() throws CoreException { IVMInstall install = JavaRuntime.getVMInstall(get14Project()); assertTrue("should be an IVMInstall2", install instanceof IVMInstall2); IVMInstall2 vm2 = (IVMInstall2) install; String prev = vm2.getVMArgs(); vm2.setVMArgs("-Dfoo=\"one two three\""); try { testWithVMArg(null, "one two three"); } finally { vm2.setVMArgs(prev); } }*/ }