diff options
Diffstat (limited to 'bundles/org.eclipse.equinox.console.tests')
42 files changed, 3739 insertions, 0 deletions
diff --git a/bundles/org.eclipse.equinox.console.tests/.classpath b/bundles/org.eclipse.equinox.console.tests/.classpath new file mode 100755 index 000000000..bb16802ac --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/.classpath @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="src" path="src"/> + <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/> + <classpathentry kind="lib" path="C:/Users/i043832/workspace_console/log4j-1.2.13.jar"/> + <classpathentry kind="lib" path="C:/Users/i043832/workspace_console/slf4j-api-1.5.11.jar"/> + <classpathentry kind="lib" path="C:/Users/i043832/workspace_console/slf4j-log4j12-1.5.11.jar"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/bundles/org.eclipse.equinox.console.tests/.gitignore b/bundles/org.eclipse.equinox.console.tests/.gitignore new file mode 100755 index 000000000..3b8360084 --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/.gitignore @@ -0,0 +1 @@ +/hostkey.ser diff --git a/bundles/org.eclipse.equinox.console.tests/.project b/bundles/org.eclipse.equinox.console.tests/.project new file mode 100755 index 000000000..7d67a8eb6 --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/.project @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.equinox.console.tests</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/bundles/org.eclipse.equinox.console.tests/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.equinox.console.tests/.settings/org.eclipse.jdt.core.prefs new file mode 100755 index 000000000..507d6a6a1 --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +#Tue Apr 12 16:03:12 EEST 2011 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/bundles/org.eclipse.equinox.console.tests/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.console.tests/META-INF/MANIFEST.MF new file mode 100755 index 000000000..04a2c18fc --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/META-INF/MANIFEST.MF @@ -0,0 +1,12 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Console supportability tests +Bundle-SymbolicName: org.eclipse.equinox.console.tests +Bundle-Version: 1.0.0.qualifier +Bundle-ActivationPolicy: lazy +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Import-Package: junit.framework;version="4.8.1", + org.apache.sshd.client.future, + org.easymock;version="2.4.0", + org.junit;version="4.8.1" +Fragment-Host: org.eclipse.equinox.console diff --git a/bundles/org.eclipse.equinox.console.tests/about.html b/bundles/org.eclipse.equinox.console.tests/about.html new file mode 100755 index 000000000..bed8451cf --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/about.html @@ -0,0 +1,28 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/> +<title>About</title> +</head> +<body lang="EN-US"> +<h2>About This Content</h2> + +<p>May 28, 2011</p> +<h3>License</h3> + +<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>. +For purposes of the EPL, "Program" will mean the Content.</p> + +<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p> + +</body> +</html>
\ No newline at end of file diff --git a/bundles/org.eclipse.equinox.console.tests/build.properties b/bundles/org.eclipse.equinox.console.tests/build.properties new file mode 100755 index 000000000..34d2e4d2d --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/Activator.java b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/Activator.java new file mode 100755 index 000000000..e024b14fa --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/Activator.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2011 SAP AG + * 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: + * Lazar Kirchev, SAP AG - initial API and implementation + *******************************************************************************/ + +package org.eclipse.equinox.console; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class Activator implements BundleActivator { + private static BundleContext context; + + public void start(BundleContext context) throws Exception { + this.context = context; + } + + + public void stop(BundleContext context) throws Exception { + this.context = null; + } + + public static BundleContext getContext() { + return context; + } +} diff --git a/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/command/adapter/ActivatorTests.java b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/command/adapter/ActivatorTests.java new file mode 100755 index 000000000..d1c3ab37b --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/command/adapter/ActivatorTests.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2011 SAP AG + * 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: + * Lazar Kirchev, SAP AG - initial API and implementation + *******************************************************************************/ + +package org.eclipse.equinox.console.command.adapter; + +import static org.junit.Assert.*; + +import java.lang.reflect.Method; +import java.util.Dictionary; +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.osgi.framework.console.CommandInterpreter; +import org.eclipse.osgi.framework.console.CommandProvider; +import org.junit.Test; + +public class ActivatorTests { + + private static final String SCOPE_PROPERTY_NAME = "osgi.command.scope"; + private static final String FUNCTION_PROPERTY_NAME = "osgi.command.function"; + private static final String EQUINOX_SCOPE = "equinox"; + + @Test + public void testGetCommandMethods() { + Set<String> commandNames = new HashSet<String>(); + commandNames.add("_testMethod1"); + commandNames.add("_testMethod2"); + commandNames.add("_testMethod3"); + + Activator activator = new Activator(); + CommandProvider command = new TestCommandProvider(); + Method[] methods = activator.getCommandMethods(command); + + assertEquals("Command methods not as expected", 3, methods.length); + for (Method method : methods) { + assertTrue("Command methods should not include " + method.getName(), commandNames.contains(method.getName())); + } + + Dictionary<String, Object> props = activator.getAttributes(methods); + assertTrue("Attributes should contain property " + SCOPE_PROPERTY_NAME + " with value " + EQUINOX_SCOPE, EQUINOX_SCOPE.equals(props.get(SCOPE_PROPERTY_NAME))); + String[] methodNames = (String[])props.get(FUNCTION_PROPERTY_NAME); + assertEquals("Methods number not as expected", methods.length, methodNames.length); + + for(int i = 0; i < methods.length; i++) { + assertEquals("Wrong method name", methods[i].getName().substring(1), methodNames[i]); + } + } + + class TestCommandProvider implements CommandProvider { + public void _testMethod1(CommandInterpreter i) { + + } + + public void _testMethod2(CommandInterpreter i) { + + } + + public void _testMethod3(CommandInterpreter i) { + + } + + private void _method(CommandInterpreter i) { + + } + + @Override + public String getHelp() { + // TODO Auto-generated method stub + return null; + } + + } + +} diff --git a/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/command/adapter/CommandProviderAdapterTest.java b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/command/adapter/CommandProviderAdapterTest.java new file mode 100755 index 000000000..b9c6c3f15 --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/command/adapter/CommandProviderAdapterTest.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2011 SAP AG + * 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: + * Lazar Kirchev, SAP AG - initial API and implementation + *******************************************************************************/ + +package org.eclipse.equinox.console.command.adapter; + +import static org.junit.Assert.*; + +import java.lang.reflect.Method; +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.osgi.framework.console.CommandInterpreter; +import org.eclipse.osgi.framework.console.CommandProvider; +import org.junit.Test; + +public class CommandProviderAdapterTest { + + @Test + public void testMain() throws Exception { + CommandProvider provider = new TestCommandProvider(); + Method[] methods = TestCommandProvider.class.getMethods(); + Set<Method> m = new HashSet<Method>(); + for (Method method : methods) { + if (method.getName().startsWith("_")) { + m.add(method); + } + } + CommandProviderAdapter providerAdapter = new CommandProviderAdapter(provider, m.toArray(new Method[0])); + + String result = (String) providerAdapter.main(new Object[] {"test"}); + assertEquals("Result should be test", "test", result); + + result = (String) providerAdapter.main(new Object[] {"echo", "hello"}); + assertEquals("Result should be hello", "hello", result); + } + + class TestCommandProvider implements CommandProvider { + public String _test(CommandInterpreter i) { + return "test"; + } + + public String _echo(CommandInterpreter i) { + return i.nextArgument(); + } + + @Override + public String getHelp() { + return "this is a test command provider"; + } + + } +} diff --git a/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/common/ConsoleInputStreamTests.java b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/common/ConsoleInputStreamTests.java new file mode 100755 index 000000000..b3732bbfc --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/common/ConsoleInputStreamTests.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2011 SAP AG + * 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: + * Lazar Kirchev, SAP AG - initial contribution + ******************************************************************************/ + +package org.eclipse.equinox.console.common; + +import org.junit.Assert; +import org.junit.Test; + +import org.eclipse.equinox.console.common.ConsoleInputStream; + +public class ConsoleInputStreamTests { + + private static final int DATA_LENGTH = 4; + + @Test + public void addReadBufferTest() throws Exception { + ConsoleInputStream in = new ConsoleInputStream(); + byte[] data = new byte[] { (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd' }; + in.add(data); + byte[] read = new byte[DATA_LENGTH]; + for (int i = 0; i < DATA_LENGTH; i++) { + in.read(read, i, 1); + Assert.assertEquals("Incorrect char read; position " + i + " expected: " + data[i] + ", actual: " + read[i], read[i], data[i]); + } + } + + @Test + public void addReadTest() throws Exception { + ConsoleInputStream in = new ConsoleInputStream(); + byte[] data = new byte[] { (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd' }; + in.add(data); + for (int i = 0; i < DATA_LENGTH; i++) { + byte symbol = (byte) in.read(); + Assert.assertEquals("Incorrect char read; position " + i + " expected: " + data[i] + ", actual: " + symbol, symbol, data[i]); + } + } +} diff --git a/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/common/ConsoleOutputStreamTests.java b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/common/ConsoleOutputStreamTests.java new file mode 100755 index 000000000..c1044ee8b --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/common/ConsoleOutputStreamTests.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2011 SAP AG + * 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: + * Lazar Kirchev, SAP AG - initial contribution + ******************************************************************************/ + +package org.eclipse.equinox.console.common; + +import org.junit.Assert; +import org.junit.Test; + +import java.io.ByteArrayOutputStream; + +public class ConsoleOutputStreamTests { + + private static final int DATA_LENGTH = 4; + + @Test + public void testWrite() throws Exception { + ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); + ConsoleOutputStream out = new ConsoleOutputStream(byteOut); + byte[] data = new byte[] { 'a', 'b', 'c', 'd' }; + for (byte b : data) { + out.write(b); + } + out.flush(); + byte[] res = byteOut.toByteArray(); + + Assert.assertNotNull("Bytes not written; result null", res); + Assert.assertFalse("Bytes not written; result empty", res.length == 0); + + for (int i = 0; i < DATA_LENGTH; i++) { + Assert.assertEquals("Wrong char read. Position " + i + ", expected " + data[i] + ", read " + res[i], data[i], res[i]); + } + } +} diff --git a/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/common/HistoryHolderTests.java b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/common/HistoryHolderTests.java new file mode 100755 index 000000000..c6321a63b --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/common/HistoryHolderTests.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2011 SAP AG + * 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: + * Lazar Kirchev, SAP AG - initial contribution + ******************************************************************************/ + +package org.eclipse.equinox.console.common; + +import org.junit.Assert; +import org.junit.Test; + +import org.eclipse.equinox.console.supportability.HistoryHolder; + +public class HistoryHolderTests { + + @Test + public void test() { + HistoryHolder historyHolder = new HistoryHolder(); + byte[] line1 = new byte[] { 'a', 'b', 'c', 'd' }; + byte[] line2 = new byte[] { 'x', 'y', 'z' }; + byte[] line3 = new byte[] { 'k', 'l', 'm', 'n' }; + + historyHolder.add(line1); + historyHolder.add(line2); + historyHolder.add(line3); + + byte[] first = historyHolder.first(); + Assert.assertEquals("Wrong length of first member", line1.length, first.length); + Assert.assertArrayEquals("Wrong first member", line1, first); + + byte[] last = historyHolder.last(); + Assert.assertEquals("Wrong length of last member", line3.length, last.length); + Assert.assertArrayEquals("Wrong last member", line3, last); + + byte[] prev = historyHolder.prev(); + Assert.assertEquals("Wrong length of previous member", line2.length, prev.length); + Assert.assertArrayEquals("Wrong previous member", line2, prev); + + byte[] next = historyHolder.next(); + Assert.assertEquals("Wrong length of next member", line3.length, next.length); + Assert.assertArrayEquals("Wrong next member", line3, next); + + historyHolder.first(); + historyHolder.add(new byte[] {}); + byte[] current = historyHolder.prev(); + Assert.assertEquals("Wrong length of next member", line3.length, current.length); + Assert.assertArrayEquals("Wrong next member", line3, current); + + historyHolder.first(); + historyHolder.add(line1); + current = historyHolder.prev(); + Assert.assertEquals("Wrong length of next member", line1.length, current.length); + Assert.assertArrayEquals("Wrong next member", line1, current); + Assert.assertArrayEquals("Second line should now be first", line2, historyHolder.first()); + + historyHolder.reset(); + Assert.assertNull("History should be empty", historyHolder.first()); + Assert.assertNull("History should be empty", historyHolder.last()); + Assert.assertNull("History should be empty", historyHolder.next()); + Assert.assertNull("History should be empty", historyHolder.prev()); + } + +} diff --git a/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/common/SimpleByteBufferTests.java b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/common/SimpleByteBufferTests.java new file mode 100755 index 000000000..9d4362431 --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/common/SimpleByteBufferTests.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright (c) 2011 SAP AG + * 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: + * Lazar Kirchev, SAP AG - initial contribution + ******************************************************************************/ + +package org.eclipse.equinox.console.common; + +import org.junit.Assert; +import org.junit.Test; + +public class SimpleByteBufferTests { + + @Test + public void testBuffer() throws Exception { + SimpleByteBuffer buffer = new SimpleByteBuffer(); + buffer.add('a'); + buffer.add('b'); + buffer.add('c'); + buffer.add('d'); + + Assert.assertTrue("Wrong buffer size; expected 4, actual " + buffer.getSize(), buffer.getSize() == 4); + + check(buffer, new byte[] { 'a', 'b', 'c', 'd' }); + + byte[] data = buffer.getCurrentData(); + byte[] expected = new byte[] { 'a', 'b', 'c', 'd' }; + + Assert.assertTrue("Data not as expected: expected length " + expected.length + ", actual length " + data.length, + data.length == expected.length); + + for (int i = 0; i < data.length; i++) { + Assert.assertEquals("Incorrect data read. Position " + i + ", expected " + expected[i] + ", read " + data[i], expected[i], data[i]); + } + + buffer.insert('a'); + buffer.insert('b'); + buffer.insert('c'); + buffer.insert('d'); + + int pos = buffer.getPos(); + buffer.goLeft(); + int newPos = buffer.getPos(); + Assert.assertEquals("Error while moving left; old pos: " + pos + ", new pos: ", pos - 1, newPos); + + buffer.insert('e'); + check(buffer, new byte[] { 'a', 'b', 'c', 'e', 'd' }); + + buffer.goLeft(); + buffer.delete(); + check(buffer, new byte[] { 'a', 'b', 'c', 'd' }); + + pos = buffer.getPos(); + buffer.goRight(); + newPos = buffer.getPos(); + Assert.assertEquals("Error while moving right; old pos: " + pos + ", new pos: ", pos + 1, newPos); + + buffer.backSpace(); + check(buffer, new byte[] { 'a', 'b', 'c' }); + + buffer.delAll(); + Assert.assertTrue("Bytes in buffer not correctly deleted", (buffer.getSize() == 0) && (buffer.getPos() == 0)); + + buffer.set(new byte[] { 'a', 'b', 'c', 'd' }); + check(buffer, new byte[] { 'a', 'b', 'c', 'd' }); + + data = buffer.copyCurrentData(); + Assert.assertArrayEquals("Buffer copy does not work properly", new byte[] { 'a', 'b', 'c', 'd' }, data); + + buffer.goLeft(); + buffer.replace('e'); + check(buffer, new byte[] { 'a', 'b', 'c', 'e' }); + + buffer.resetPos(); + Assert.assertTrue("Resetting position does not work properly", buffer.getPos() == 0); + + Assert.assertEquals("Wrong current char", 'a', buffer.getCurrentChar()); + } + + private void check(SimpleByteBuffer buffer, byte[] expected) throws Exception { + byte[] data = buffer.copyCurrentData(); + + Assert.assertTrue("Data not as expected: expected length " + expected.length + ", actual length " + data.length, + data.length == expected.length); + + for (int i = 0; i < data.length; i++) { + Assert.assertEquals("Incorrect data read. Position " + i + ", expected " + expected[i] + ", read " + data[i], expected[i], data[i]); + } + } + +} diff --git a/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/completion/CommandLineParserTests.java b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/completion/CommandLineParserTests.java new file mode 100755 index 000000000..408c8a8f1 --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/completion/CommandLineParserTests.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2011 SAP AG + * 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: + * Lazar Kirchev, SAP AG - initial API and implementation + *******************************************************************************/ + +package org.eclipse.equinox.console.completion; + +import static org.junit.Assert.*; + +import org.junit.Test; + +public class CommandLineParserTests { + + private static final String PIPE_TEST_INPUT = "command1|comm"; + private static final String CONSECUTIVE_COMMANDS_TEST_INPUT = "command1;comm"; + private static final String ASSIGNMENT_TEST_INPUT = "var=val"; + private static final String START_CLOSURE_TEST_INPUT = "${comm"; + private static final String END_CLOSURE_TEST_INPUT = "${command}arg1"; + private static final String START_MACRO_TEST_INPUT = "$(macr"; + private static final String END_MACRO_TEST_INPUT = "$(macro)val"; + private static final String VARIABLE_TEST_INPUT = "$VAR"; + private static final String START_MAP_TEST_INPUT = "<key=val"; + private static final String END_MAP_TEST_INPUT = "<key=val>other"; + private static final String START_LIST_TEST_INPUT = "[elem1,elem2,el"; + private static final String LIST_TEST_INPUT = "[elem1, elem2, elem3]other"; + private static final String COMMAND_ARGUMENTS_TEST_INPUT = "command argument1 argum"; + private static final String COMMAND_NAME_TEST_INPUT = "com"; + private static final String COMMENT_TEST_INPUT="command#comment"; + + @Test + public void testGetCurrentToken() { + String token; + + token = CommandLineParser.getCurrentToken(PIPE_TEST_INPUT, PIPE_TEST_INPUT.length()); + assertEquals("Pipe not parsed correctly", "comm", token); + + token = CommandLineParser.getCurrentToken(CONSECUTIVE_COMMANDS_TEST_INPUT, CONSECUTIVE_COMMANDS_TEST_INPUT.length()); + assertEquals("Consequtive commands not parsed correctly", "comm", token); + + token = CommandLineParser.getCurrentToken(ASSIGNMENT_TEST_INPUT, ASSIGNMENT_TEST_INPUT.length()); + assertEquals("Assignment not parsed correctly", "val", token); + + token = CommandLineParser.getCurrentToken(START_CLOSURE_TEST_INPUT, START_CLOSURE_TEST_INPUT.length()); + assertEquals("Start closure not parsed correctly", "comm", token); + + token = CommandLineParser.getCurrentToken(END_CLOSURE_TEST_INPUT, END_CLOSURE_TEST_INPUT.length()); + assertEquals("End closure not parsed correctly", "arg1", token); + + token = CommandLineParser.getCurrentToken(START_MACRO_TEST_INPUT, START_MACRO_TEST_INPUT.length()); + assertEquals("Start macro not parsed correctly", "macr", token); + + token = CommandLineParser.getCurrentToken(END_MACRO_TEST_INPUT, END_MACRO_TEST_INPUT.length()); + assertEquals("End macro not parsed correctly", "val", token); + + token = CommandLineParser.getCurrentToken(VARIABLE_TEST_INPUT, VARIABLE_TEST_INPUT.length()); + assertEquals("Variable name not parsed correctly", "VAR", token); + + token = CommandLineParser.getCurrentToken(START_MAP_TEST_INPUT, START_MAP_TEST_INPUT.length()); + assertNull("Start map not parsed correctly", token); + + token = CommandLineParser.getCurrentToken(END_MAP_TEST_INPUT, END_MAP_TEST_INPUT.length()); + assertEquals("End map not parsed correctly", "other", token); + + token = CommandLineParser.getCurrentToken(START_LIST_TEST_INPUT, START_LIST_TEST_INPUT.length()); + assertNull("Start list not parsed correctly", token); + + token = CommandLineParser.getCurrentToken(LIST_TEST_INPUT, LIST_TEST_INPUT.length()); + assertEquals("List not parsed correctly", "other", token); + + token = CommandLineParser.getCurrentToken(COMMAND_ARGUMENTS_TEST_INPUT, COMMAND_ARGUMENTS_TEST_INPUT.length()); + assertEquals("Command with arguments not parsed correctly", "argum", token); + + token = CommandLineParser.getCurrentToken(COMMAND_NAME_TEST_INPUT, COMMAND_NAME_TEST_INPUT.length()); + assertEquals("Command name not parsed correctly", "com", token); + + token = CommandLineParser.getCurrentToken(COMMENT_TEST_INPUT, COMMENT_TEST_INPUT.length()); + assertNull("Comment not parsed correctly", token); + } + +} diff --git a/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/completion/CommandNamesCompleterTests.java b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/completion/CommandNamesCompleterTests.java new file mode 100755 index 000000000..390ffa743 --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/completion/CommandNamesCompleterTests.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2011 SAP AG + * 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: + * Lazar Kirchev, SAP AG - initial API and implementation + *******************************************************************************/ + +package org.eclipse.equinox.console.completion; + +import static org.junit.Assert.*; +import static org.easymock.EasyMock.*; + +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.apache.felix.service.command.CommandSession; +import org.junit.Test; + +public class CommandNamesCompleterTests { + + private static final String COMMANDS = ".commands"; + + @Test + public void testGetCandidates() { + Set<String> commands = new HashSet<String>(); + commands.add("equinox:bundles"); + commands.add("equinox:diag"); + commands.add("equinox:setprop"); + commands.add("gogo:lb"); + commands.add("gogo:echo"); + commands.add("gogo:set"); + + CommandSession session = createMock(CommandSession.class); + expect(session.get(COMMANDS)).andReturn(commands).times(4); + replay(session); + + CommandNamesCompleter completer = new CommandNamesCompleter(session); + Map<String, Integer> candidates; + + candidates = completer.getCandidates("se", 2); + assertNotNull("Candidates null", candidates); + assertEquals("Candidates not as expected", 2, candidates.size()); + assertNotNull("set should be in the resultset, but it is not", candidates.get("set")); + assertNotNull("setprop should be in the resultset, but it is not", candidates.get("setprop")); + + candidates = completer.getCandidates("equinox:bun", "equinox:bun".length()); + assertNotNull("Candidates null", candidates); + assertEquals("Candidates not as expected", 1, candidates.size()); + assertNotNull("equinox:bundles should be in the resultset, but it is not", candidates.get("equinox:bundles")); + + candidates = completer.getCandidates("ec", 2); + assertNotNull("Candidates null", candidates); + assertEquals("Candidates not as expected", 1, candidates.size()); + assertNotNull("echo should be in the resultset, but it is not", candidates.get("echo")); + + candidates = completer.getCandidates("head", 4); + assertNotNull("Candidates null", candidates); + assertEquals("Candidates not as expected", 0, candidates.size()); + + verify(session); + } + +} diff --git a/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/completion/CompletionHandlerTests.java b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/completion/CompletionHandlerTests.java new file mode 100755 index 000000000..e71be0c12 --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/completion/CompletionHandlerTests.java @@ -0,0 +1,165 @@ +/******************************************************************************* + * Copyright (c) 2011 SAP AG + * 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: + * Lazar Kirchev, SAP AG - initial API and implementation + *******************************************************************************/ + +package org.eclipse.equinox.console.completion; + +import static org.junit.Assert.*; +import static org.easymock.EasyMock.*; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.apache.felix.service.command.CommandSession; +import org.eclipse.equinox.console.completion.common.Completer; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.osgi.framework.BundleContext; + +public class CompletionHandlerTests { + + private static final String COMMANDS = ".commands"; + private static final String WORK_DIR_NAME = "work"; + private static final String TESTFILE = "testfile"; + private static final String TESTOUTPUT = "testoutput"; + private static final String FILE = "file"; + + @Before + public void init() throws IOException { + File currentDir = new File("."); + File[] files = currentDir.listFiles(); + for (File file : files) { + if(file.getName().equals(WORK_DIR_NAME)) { + clean(); + break; + } + } + + File workDir = new File(currentDir.getAbsolutePath() + File.separator + WORK_DIR_NAME); + workDir.mkdir(); + + createFile(workDir, TESTFILE); + createFile(workDir, TESTOUTPUT); + createFile(workDir, FILE); + } + + @Test + public void testGetCandidates() throws Exception { + BundleContext context = createMock(BundleContext.class); + expect(context.getServiceReferences(Completer.class.getName(), null)).andReturn(null).anyTimes(); + replay(context); + + Set<String> variables = new HashSet<String>(); + variables.add("SCOPE"); + variables.add("PROMPT"); + variables.add("ECHO_ON"); + variables.add("ECHO"); + + Set<String> commands = new HashSet<String>(); + commands.add("equinox:bundles"); + commands.add("equinox:diag"); + commands.add("equinox:setprop"); + commands.add("gogo:lb"); + commands.add("gogo:echo"); + commands.add("gogo:set"); + + CommandSession session = createMock(CommandSession.class); + expect(session.get(null)).andReturn(variables).anyTimes(); + expect(session.get(COMMANDS)).andReturn(commands).anyTimes(); + replay(session); + + CompletionHandler completer = new CompletionHandler(context, session); + Map<String, Integer> candidates; + + candidates = completer.getCandidates("$SC".getBytes(), 2); + assertNotNull("Candidates null", candidates); + assertEquals("Candidates not as expected", 1, candidates.size()); + assertNotNull("SCOPE should be in the resultset, but it is not", candidates.get("SCOPE")); + + candidates = completer.getCandidates("$EC".getBytes(), 2); + assertNotNull("Candidates null", candidates); + assertEquals("Candidates not as expected", 2, candidates.size()); + assertNotNull("ECHO_ON should be in the resultset, but it is not", candidates.get("ECHO_ON")); + assertNotNull("ECHO should be in the resultset, but it is not", candidates.get("ECHO")); + + candidates = completer.getCandidates("$AB".getBytes(), 2); + assertNotNull("Candidates null", candidates); + assertEquals("Candidates not as expected", 0, candidates.size()); + + completer = new CompletionHandler(context, session); + candidates = completer.getCandidates("se".getBytes(), 2); + assertNotNull("Candidates null", candidates); + assertEquals("Candidates not as expected", 2, candidates.size()); + assertNotNull("set should be in the resultset, but it is not", candidates.get("set")); + assertNotNull("setprop should be in the resultset, but it is not", candidates.get("setprop")); + + candidates = completer.getCandidates("equinox:bun".getBytes(), "equinox:bun".length()); + assertNotNull("Candidates null", candidates); + assertEquals("Candidates not as expected", 1, candidates.size()); + assertNotNull("equinox:bundles should be in the resultset, but it is not", candidates.get("equinox:bundles")); + + candidates = completer.getCandidates("ec".getBytes(), 2); + assertNotNull("Candidates null", candidates); + assertEquals("Candidates not as expected", 1, candidates.size()); + assertNotNull("echo should be in the resultset, but it is not", candidates.get("echo")); + + candidates = completer.getCandidates("head".getBytes(), "head".length()); + assertNotNull("Candidates null", candidates); + assertEquals("Candidates not as expected", 0, candidates.size()); + + completer = new CompletionHandler(context, session); + candidates = completer.getCandidates("wor".getBytes(), "wor".length()); + assertNotNull("Candidates null", candidates); + assertEquals("Candidates not as expected", 1, candidates.size()); + assertNotNull("work should be in the resultset, but it is not", candidates.get(WORK_DIR_NAME)); + + candidates = completer.getCandidates("work/test".getBytes(), "work/test".length()); + assertNotNull("Candidates null", candidates); + assertEquals("Candidates not as expected", 2, candidates.size()); + assertNotNull("testfile should be in the resultset, but it is not", candidates.get(TESTFILE)); + assertNotNull("testoutput should be in the resultset, but it is not", candidates.get(TESTOUTPUT)); + + candidates = completer.getCandidates("work/".getBytes(), "work/".length()); + assertEquals("Candidates not as expected", 3, candidates.size()); + assertNotNull("testfile should be in the resultset, but it is not", candidates.get(TESTFILE)); + assertNotNull("testoutput should be in the resultset, but it is not", candidates.get(TESTOUTPUT)); + assertNotNull("file should be in the resultset, but it is not", candidates.get(FILE)); + } + + @After + public void cleanUp() { + clean(); + } + + private void clean() { + File currentFile = new File("."); + File workDir = new File(currentFile.getAbsolutePath() + File.separator + WORK_DIR_NAME); + File[] files = workDir.listFiles(); + for (File file : files) { + file.delete(); + } + workDir.delete(); + } + + private void createFile(File parentDir, String filename) throws IOException { + File file = new File(parentDir.getAbsolutePath() + File.separator + filename); + PrintWriter out = new PrintWriter(new FileOutputStream(file)); + out.write(filename); + out.flush(); + out.close(); + } + +} diff --git a/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/completion/FileNamesCompleterTests.java b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/completion/FileNamesCompleterTests.java new file mode 100755 index 000000000..91540a13f --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/completion/FileNamesCompleterTests.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright (c) 2011 SAP AG + * 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: + * Lazar Kirchev, SAP AG - initial API and implementation + *******************************************************************************/ + +package org.eclipse.equinox.console.completion; + +import static org.junit.Assert.*; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Map; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class FileNamesCompleterTests { + private static final String WORK_DIR_NAME = "work"; + private static final String TESTFILE = "testfile"; + private static final String TESTOUTPUT = "testoutput"; + private static final String FILE = "file"; + + @Before + public void init() throws IOException { + File currentDir = new File("."); + File[] files = currentDir.listFiles(); + for (File file : files) { + if(file.getName().equals(WORK_DIR_NAME)) { + clean(); + break; + } + } + + File workDir = new File(currentDir.getAbsolutePath() + File.separator + WORK_DIR_NAME); + workDir.mkdir(); + + createFile(workDir, TESTFILE); + createFile(workDir, TESTOUTPUT); + createFile(workDir, FILE); + } + + @Test + public void testGetCandidates() { + FileNamesCompleter completer = new FileNamesCompleter(); + + Map<String, Integer> candidates; + + candidates = completer.getCandidates("wor", "wor".length()); + assertNotNull("Candidates null", candidates); + assertEquals("Candidates not as expected", 1, candidates.size()); + assertNotNull("work should be in the resultset, but it is not", candidates.get(WORK_DIR_NAME)); + + candidates = completer.getCandidates("work/test", "work/test".length()); + assertNotNull("Candidates null", candidates); + assertEquals("Candidates not as expected", 2, candidates.size()); + assertNotNull("testfile should be in the resultset, but it is not", candidates.get(TESTFILE)); + assertNotNull("testoutput should be in the resultset, but it is not", candidates.get(TESTOUTPUT)); + + candidates = completer.getCandidates(WORK_DIR_NAME + "/", 5); + assertEquals("Candidates not as expected", 3, candidates.size()); + assertNotNull("testfile should be in the resultset, but it is not", candidates.get(TESTFILE)); + assertNotNull("testoutput should be in the resultset, but it is not", candidates.get(TESTOUTPUT)); + assertNotNull("file should be in the resultset, but it is not", candidates.get(FILE)); + } + + @After + public void cleanUp() { + clean(); + } + + private void clean() { + File currentFile = new File("."); + File workDir = new File(currentFile.getAbsolutePath() + File.separator + WORK_DIR_NAME); + File[] files = workDir.listFiles(); + for (File file : files) { + file.delete(); + } + workDir.delete(); + } + + private void createFile(File parentDir, String filename) throws IOException { + File file = new File(parentDir.getAbsolutePath() + File.separator + filename); + PrintWriter out = new PrintWriter(new FileOutputStream(file)); + out.write(filename); + out.flush(); + out.close(); + } +} diff --git a/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/completion/StringsCompleterTests.java b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/completion/StringsCompleterTests.java new file mode 100755 index 000000000..05096ba5b --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/completion/StringsCompleterTests.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2011 SAP AG + * 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: + * Lazar Kirchev, SAP AG - initial API and implementation + *******************************************************************************/ + +package org.eclipse.equinox.console.completion; + +import static org.junit.Assert.*; + +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.junit.Test; + +public class StringsCompleterTests { + + @Test + public void testGetCandidates() { + Set<String> strings = new HashSet<String>(); + strings.add("command"); + strings.add("SCOPE"); + strings.add("equinox:bundles"); + strings.add("common"); + + StringsCompleter completer = new StringsCompleter(strings, false); + Map<String, Integer> candidates; + + candidates = completer.getCandidates("sco", 3); + assertNotNull("Candidates null", candidates); + assertEquals("Candidates not as expected", 1, candidates.size()); + assertNotNull("SCOPE should be in the resultset, but it is not", candidates.get("SCOPE")); + + candidates = completer.getCandidates("com", 3); + assertNotNull("Candidates null", candidates); + assertEquals("Candidates not as expected", 2, candidates.size()); + assertNotNull("command should be in the resultset, but it is not", candidates.get("command")); + assertNotNull("common should be in the resultset, but it is not", candidates.get("common")); + + candidates = completer.getCandidates("tr", 2); + assertNotNull("Candidates null", candidates); + assertEquals("Candidates not as expected", 0, candidates.size()); + + completer = new StringsCompleter(strings, true); + + candidates = completer.getCandidates("sco", 3); + assertNotNull("Candidates null", candidates); + assertEquals("Candidates not as expected", 0, candidates.size()); + + candidates = completer.getCandidates("SCO", 3); + assertNotNull("Candidates null", candidates); + assertEquals("Candidates not as expected", 1, candidates.size()); + assertNotNull("SCOPE should be in the resultset, but it is not", candidates.get("SCOPE")); + } + +} diff --git a/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/completion/VariableNamesCompleterTests.java b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/completion/VariableNamesCompleterTests.java new file mode 100755 index 000000000..2b6ca5290 --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/completion/VariableNamesCompleterTests.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2011 SAP AG + * 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: + * Lazar Kirchev, SAP AG - initial API and implementation + *******************************************************************************/ + +package org.eclipse.equinox.console.completion; + +import static org.easymock.EasyMock.*; +import static org.junit.Assert.*; + +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.apache.felix.service.command.CommandSession; +import org.junit.Test; + +public class VariableNamesCompleterTests { + + @Test + public void testGetCandidates() { + Set<String> variables = new HashSet<String>(); + variables.add("SCOPE"); + variables.add("PROMPT"); + variables.add("ECHO_ON"); + variables.add("ECHO"); + + CommandSession session = createMock(CommandSession.class); + expect(session.get(null)).andReturn(variables).times(3); + replay(session); + + VariableNamesCompleter completer = new VariableNamesCompleter(session); + Map<String, Integer> candidates; + + candidates = completer.getCandidates("SC", 2); + assertNotNull("Candidates null", candidates); + assertEquals("Candidates not as expected", 1, candidates.size()); + assertNotNull("SCOPE should be in the resultset, but it is not", candidates.get("SCOPE")); + + candidates = completer.getCandidates("EC", 2); + assertNotNull("Candidates null", candidates); + assertEquals("Candidates not as expected", 2, candidates.size()); + assertNotNull("ECHO_ON should be in the resultset, but it is not", candidates.get("ECHO_ON")); + assertNotNull("ECHO should be in the resultset, but it is not", candidates.get("ECHO")); + + candidates = completer.getCandidates("AB", 2); + assertNotNull("Candidates null", candidates); + assertEquals("Candidates not as expected", 0, candidates.size()); + + verify(session); + } + +} diff --git a/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/jaas/RolePrincipalTests.java b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/jaas/RolePrincipalTests.java new file mode 100755 index 000000000..edae26f3b --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/jaas/RolePrincipalTests.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2011 SAP AG + * 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: + * Lazar Kirchev, SAP AG - initial API and implementation + *******************************************************************************/ + +package org.eclipse.equinox.console.jaas; + +import static org.junit.Assert.*; + +import org.junit.Test; + +public class RolePrincipalTests { + + private static final String ROLE_NAME = "administrator"; + + @Test + public void testHashCode() { + RolePrincipal role = new RolePrincipal(ROLE_NAME); + assertEquals("Role hash code not as expected", 73 + ROLE_NAME.hashCode(), role.hashCode()); + } + + @Test + public void testGetName() { + RolePrincipal role = new RolePrincipal(ROLE_NAME); + assertEquals("Role not as expected", ROLE_NAME, role.getName()); + } + + @Test + public void testEqualsObject() { + RolePrincipal role = new RolePrincipal(ROLE_NAME); + RolePrincipal sameRole = new RolePrincipal(ROLE_NAME); + RolePrincipal emptyRole = new RolePrincipal(null); + + assertTrue("Roles should be equal", role.equals(role)); + assertTrue("Roles should be equal", role.equals(sameRole)); + assertFalse("Roles should not be equal", role.equals(emptyRole)); + } + +} diff --git a/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/jaas/UserPrincipalTests.java b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/jaas/UserPrincipalTests.java new file mode 100755 index 000000000..50239be1c --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/jaas/UserPrincipalTests.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright (c) 2011 SAP AG + * 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: + * Lazar Kirchev, SAP AG - initial API and implementation + *******************************************************************************/ + +package org.eclipse.equinox.console.jaas; + +import static org.junit.Assert.*; + +import java.util.Set; + +import org.junit.BeforeClass; +import org.junit.Test; + +public class UserPrincipalTests { + + private static final String USERNAME = "username"; + private static final String PASSWORD = "password"; + private static final String OTHERUSER = "otheruser"; + private static final String OTHERPASSWORD = "otherpass"; + private static final String WRONG_PASS = "wrong_pass"; + private static final String ROLE = "administrator"; + private static final String OTHERROLE = "otherrole"; + + @Test + public void testHashCode() { + UserPrincipal user = new UserPrincipal(USERNAME, PASSWORD); + RolePrincipal role = new RolePrincipal(ROLE); + user.addRole(role); + + int expectedHash = 73 + USERNAME.hashCode(); + expectedHash = 73*expectedHash + PASSWORD.hashCode(); + expectedHash = 73*expectedHash + role.hashCode(); + assertEquals("User hash code not as expected", expectedHash, user.hashCode()); + } + + @Test + public void testGetName() { + UserPrincipal user = new UserPrincipal(USERNAME, PASSWORD); + assertEquals("Username not as expected", USERNAME, user.getName()); + } + + @Test + public void testAuthenticate() { + UserPrincipal user = new UserPrincipal(USERNAME, PASSWORD); + assertTrue("User should be successfully authenticated", user.authenticate(PASSWORD.toCharArray())); + assertFalse("User should not be authenticated", user.authenticate(WRONG_PASS.toCharArray())); + } + + @Test + public void testGetRoles() { + UserPrincipal user = new UserPrincipal(USERNAME, PASSWORD); + RolePrincipal role = new RolePrincipal(ROLE); + user.addRole(role); + Set<RolePrincipal> roles = user.getRoles(); + assertEquals("There should be one role", 1, roles.size()); + assertTrue("User roles should contain the role administrator", roles.contains(role)); + } + + @Test + public void testEqualsObject() { + UserPrincipal user = new UserPrincipal(USERNAME, PASSWORD); + RolePrincipal role = new RolePrincipal(ROLE); + user.addRole(role); + + UserPrincipal sameUser = new UserPrincipal(USERNAME, PASSWORD); + RolePrincipal sameRole = new RolePrincipal(ROLE); + sameUser.addRole(sameRole); + + UserPrincipal otherUser = new UserPrincipal(OTHERUSER, OTHERPASSWORD); + RolePrincipal otherRole = new RolePrincipal(OTHERROLE); + otherUser.addRole(otherRole); + + UserPrincipal userOtherRole = new UserPrincipal(USERNAME, PASSWORD); + RolePrincipal otherRolePrincipal = new RolePrincipal(OTHERROLE); + userOtherRole.addRole(otherRolePrincipal); + + assertTrue("User should be equal to itself", user.equals(user)); + assertTrue("Users should be equal", user.equals(sameUser)); + assertFalse("Users should not be equal", user.equals(otherUser)); + assertFalse("Users should not be equal", user.equals(userOtherRole)); + } + + @Test + public void testDestroy() { + UserPrincipal user = new UserPrincipal(USERNAME, PASSWORD); + UserPrincipal same = new UserPrincipal(USERNAME, PASSWORD); + + user.destroy(); + assertFalse("Users should not be equal", user.equals(same)); + } + +} diff --git a/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/ssh/SshCommandTests.java b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/ssh/SshCommandTests.java new file mode 100755 index 000000000..7fab9788b --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/ssh/SshCommandTests.java @@ -0,0 +1,188 @@ +/******************************************************************************* + * Copyright (c) 2011 SAP AG + * 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: + * Lazar Kirchev, SAP AG - initial API and implementation + *******************************************************************************/ + +package org.eclipse.equinox.console.ssh; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.StringBufferInputStream; +import java.util.Dictionary; +import java.util.HashMap; +import java.util.Map; + +import org.apache.felix.service.command.CommandProcessor; +import org.apache.felix.service.command.CommandSession; +import org.apache.sshd.ClientChannel; +import org.apache.sshd.ClientSession; +import org.apache.sshd.SshClient; +import org.apache.sshd.client.future.ConnectFuture; +import org.apache.sshd.client.future.DefaultConnectFuture; +import org.apache.sshd.server.Environment; +import org.easymock.EasyMock; +import org.eclipse.equinox.console.common.ConsoleInputStream; +import org.eclipse.equinox.console.storage.DigestUtil; +import org.eclipse.equinox.console.storage.SecureUserStore; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.osgi.framework.BundleContext; + + +public class SshCommandTests { + private static final int TEST_CONTENT = 100; + private static final String USER_STORE_FILE_NAME = "org.eclipse.equinox.console.jaas.file"; + private static final String JAAS_CONFIG_FILE_NAME = "jaas.config"; + private static final String JAAS_CONFIG_PROPERTY_NAME = "java.security.auth.login.config"; + private static final String DEFAULT_USER_STORAGE = "osgi.console.ssh.useDefaultSecureStorage"; + private static final String SSH_PORT_PROP_NAME = "osgi.console.ssh"; + private static final String USE_CONFIG_ADMIN_PROP = "osgi.console.useConfigAdmin"; + private static final String STORE_FILE_NAME = SshCommandTests.class.getName() + "_store"; + private static final String GOGO_SHELL_COMMAND = "gosh --login --noshutdown"; + private static final String TRUE = "true"; + private static final String FALSE = "false"; + private static final String USERNAME = "username"; + private static final String PASSWORD = "password"; + private static final String START_COMMAND = "start"; + private static final String STOP_COMMAND = "stop"; + private static final String TERM_PROPERTY = "TERM"; + private static final String XTERM = "XTERM"; + private static final String HOST = "localhost"; + private static final int SSH_PORT = 2222; + private static final long WAIT_TIME = 5000; + + @Before + public void init() throws Exception { + clean(); + initStore(); + initJaasConfigFile(); + } + + @Test + public void testSshCommand() throws Exception { + CommandSession session = EasyMock.createMock(CommandSession.class); + EasyMock.makeThreadSafe(session, true); + session.put((String)EasyMock.anyObject(), EasyMock.anyObject()); + EasyMock.expectLastCall().times(5); + EasyMock.expect(session.execute(GOGO_SHELL_COMMAND)).andReturn(null); + session.close(); + EasyMock.expectLastCall(); + EasyMock.replay(session); + + CommandProcessor processor = EasyMock.createMock(CommandProcessor.class); + EasyMock.expect(processor.createSession((ConsoleInputStream)EasyMock.anyObject(), (PrintStream)EasyMock.anyObject(), (PrintStream)EasyMock.anyObject())).andReturn(session); + EasyMock.replay(processor); + + BundleContext context = EasyMock.createMock(BundleContext.class); + EasyMock.makeThreadSafe(context, true); + EasyMock.expect(context.getProperty(USE_CONFIG_ADMIN_PROP)).andReturn(FALSE); + EasyMock.expect(context.getProperty(DEFAULT_USER_STORAGE)).andReturn(TRUE).anyTimes(); + EasyMock.expect(context.getProperty(SSH_PORT_PROP_NAME)).andReturn(Integer.toString(SSH_PORT)); + EasyMock.expect(context.registerService((String)EasyMock.anyObject(), EasyMock.anyObject(), (Dictionary<String, ?>)EasyMock.anyObject())).andReturn(null); + EasyMock.replay(context); + + Map<String, String> environment = new HashMap<String, String>(); + environment.put(TERM_PROPERTY, XTERM); + Environment env = EasyMock.createMock(Environment.class); + EasyMock.expect(env.getEnv()).andReturn(environment); + EasyMock.replay(env); + + SshCommand command = new SshCommand(processor, context); + command.ssh(new String[] {START_COMMAND}); + + SshClient client = SshClient.setUpDefaultClient(); + client.start(); + try { + ConnectFuture connectFuture = client.connect(HOST, SSH_PORT); + DefaultConnectFuture defaultConnectFuture = (DefaultConnectFuture) connectFuture; + + try { + Thread.sleep(WAIT_TIME); + } catch (InterruptedException ie) { + // do nothing + } + ClientSession sshSession = defaultConnectFuture.getSession(); + + int ret = ClientSession.WAIT_AUTH; + sshSession.authPassword(USERNAME, PASSWORD); + ret = sshSession.waitFor(ClientSession.WAIT_AUTH | ClientSession.CLOSED | ClientSession.AUTHED, 0); + + if ((ret & ClientSession.CLOSED) != 0) { + System.err.println("error"); + System.exit(-1); + } + ClientChannel channel = sshSession.createChannel("shell"); + channel.setIn(new StringBufferInputStream(TEST_CONTENT + "\n")); + ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); + channel.setOut(byteOut); + channel.setErr(byteOut); + channel.open(); + try { + Thread.sleep(WAIT_TIME); + } catch (InterruptedException ie) { + // do nothing + } + byte[] output = byteOut.toByteArray(); + Assert.assertEquals("Output not as expected",Integer.toString(TEST_CONTENT), new String(output).trim()); + sshSession.close(true); + } finally { + client.stop(); + } + + command.ssh(new String[] {STOP_COMMAND}); + return; + } + + @After + public void cleanUp() { + clean(); + } + + private void clean() { + System.setProperty(USER_STORE_FILE_NAME, ""); + File file = new File(STORE_FILE_NAME); + if (file.exists()) { + file.delete(); + } + + System.setProperty(JAAS_CONFIG_PROPERTY_NAME, ""); + File jaasConfFile = new File(JAAS_CONFIG_FILE_NAME); + if (jaasConfFile.exists()) { + jaasConfFile.delete(); + } + } + + private void initStore() throws Exception { + System.setProperty(USER_STORE_FILE_NAME, STORE_FILE_NAME); + SecureUserStore.initStorage(); + SecureUserStore.putUser(USERNAME, DigestUtil.encrypt(PASSWORD), null); + } + + private void initJaasConfigFile() throws Exception { + System.setProperty(JAAS_CONFIG_PROPERTY_NAME, JAAS_CONFIG_FILE_NAME); + File jaasConfFile = new File(JAAS_CONFIG_FILE_NAME); + if (!jaasConfFile.exists()) { + PrintWriter out = null; + try { + out = new PrintWriter(jaasConfFile); + out.println("equinox_console {"); + out.println(" org.eclipse.equinox.console.jaas.SecureStorageLoginModule REQUIRED;"); + out.println("};"); + } finally { + if (out != null) { + out.close(); + } + } + } + } +} diff --git a/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/ssh/SshCommandWithConfigAdminTests.java b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/ssh/SshCommandWithConfigAdminTests.java new file mode 100755 index 000000000..099442d77 --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/ssh/SshCommandWithConfigAdminTests.java @@ -0,0 +1,310 @@ +package org.eclipse.equinox.console.ssh; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.InputStream; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.StringBufferInputStream; +import java.util.Collection; +import java.util.Dictionary; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Map; + +import org.apache.felix.service.command.CommandProcessor; +import org.apache.felix.service.command.CommandSession; +import org.apache.sshd.ClientChannel; +import org.apache.sshd.ClientSession; +import org.apache.sshd.SshClient; +import org.apache.sshd.client.future.ConnectFuture; +import org.apache.sshd.client.future.DefaultConnectFuture; +import org.apache.sshd.common.RuntimeSshException; +import org.apache.sshd.server.Environment; +import org.easymock.EasyMock; +import org.easymock.IAnswer; +import org.eclipse.equinox.console.common.ConsoleInputStream; +import org.eclipse.equinox.console.storage.DigestUtil; +import org.eclipse.equinox.console.storage.SecureUserStore; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleException; +import org.osgi.framework.BundleListener; +import org.osgi.framework.Filter; +import org.osgi.framework.FrameworkListener; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceListener; +import org.osgi.framework.ServiceReference; +import org.osgi.framework.ServiceRegistration; +import org.osgi.service.cm.ManagedService; + + +public class SshCommandWithConfigAdminTests { + private static final int TEST_CONTENT = 100; + private static final String USER_STORE_FILE_NAME = "org.eclipse.equinox.console.jaas.file"; + private static final String JAAS_CONFIG_FILE_NAME = "jaas.config"; + private static final String JAAS_CONFIG_PROPERTY_NAME = "java.security.auth.login.config"; + private static final String DEFAULT_USER_STORAGE = "osgi.console.ssh.useDefaultSecureStorage"; + private static final String STORE_FILE_NAME = SshCommandTests.class.getName() + "_store"; + private static final String GOGO_SHELL_COMMAND = "gosh --login --noshutdown"; + private static final String TRUE = "true"; + private static final String FALSE = "false"; + private static final String USERNAME = "username"; + private static final String PASSWORD = "password"; + private static final String STOP_COMMAND = "stop"; + private static final String TERM_PROPERTY = "TERM"; + private static final String XTERM = "XTERM"; + private static final String HOST = "localhost"; + private static final String SSH_PORT = "2222"; + private static final long WAIT_TIME = 5000; + private static final String USE_CONFIG_ADMIN_PROP = "osgi.console.useConfigAdmin"; + private ManagedService configurator; + + @Before + public void init() throws Exception { + clean(); + initStore(); + initJaasConfigFile(); + } + + @Test + public void testSshCommandWithConfigAdmin() throws Exception { + + CommandSession session = EasyMock.createMock(CommandSession.class); + EasyMock.makeThreadSafe(session, true); + session.put((String)EasyMock.anyObject(), EasyMock.anyObject()); + EasyMock.expectLastCall().times(5); + EasyMock.expect(session.execute(GOGO_SHELL_COMMAND)).andReturn(null); + session.close(); + EasyMock.expectLastCall(); + EasyMock.replay(session); + + CommandProcessor processor = EasyMock.createMock(CommandProcessor.class); + EasyMock.expect(processor.createSession((ConsoleInputStream)EasyMock.anyObject(), (PrintStream)EasyMock.anyObject(), (PrintStream)EasyMock.anyObject())).andReturn(session); + EasyMock.replay(processor); + + final ServiceRegistration<?> registration = EasyMock.createMock(ServiceRegistration.class); + registration.setProperties((Dictionary)EasyMock.anyObject()); + EasyMock.expectLastCall(); + EasyMock.replay(registration); + + BundleContext context = EasyMock.createMock(BundleContext.class); + EasyMock.makeThreadSafe(context, true); + EasyMock.expect(context.getProperty(USE_CONFIG_ADMIN_PROP)).andReturn(TRUE); + EasyMock.expect(context.getProperty(DEFAULT_USER_STORAGE)).andReturn(TRUE).anyTimes(); + EasyMock.expect( + (ServiceRegistration) context.registerService( + (String)EasyMock.anyObject(), + (ManagedService)EasyMock.anyObject(), + (Dictionary<String, ?>)EasyMock.anyObject()) + ).andAnswer((IAnswer<ServiceRegistration<?>>) new IAnswer<ServiceRegistration<?>>() { + public ServiceRegistration<?> answer() { + configurator = (ManagedService) EasyMock.getCurrentArguments()[1]; + return registration; + } + }); + EasyMock.expect( + context.registerService( + (String)EasyMock.anyObject(), + (SshCommand)EasyMock.anyObject(), + (Dictionary<String, ?>)EasyMock.anyObject())).andReturn(null); + EasyMock.replay(context); + + Map<String, String> environment = new HashMap<String, String>(); + environment.put(TERM_PROPERTY, XTERM); + Environment env = EasyMock.createMock(Environment.class); + EasyMock.expect(env.getEnv()).andReturn(environment); + EasyMock.replay(env); + + SshCommand command = new SshCommand(processor, context); + Dictionary props = new Hashtable(); + props.put("port", SSH_PORT); + props.put("host", HOST); + props.put("enabled", TRUE); + configurator.updated(props); + + SshClient client = SshClient.setUpDefaultClient(); + client.start(); + try { + ConnectFuture connectFuture = client.connect(HOST, Integer.valueOf(SSH_PORT)); + DefaultConnectFuture defaultConnectFuture = (DefaultConnectFuture) connectFuture; + + try { + Thread.sleep(WAIT_TIME); + } catch (InterruptedException ie) { + // do nothing + } + ClientSession sshSession = defaultConnectFuture.getSession(); + + int ret = ClientSession.WAIT_AUTH; + sshSession.authPassword(USERNAME, PASSWORD); + ret = sshSession.waitFor(ClientSession.WAIT_AUTH | ClientSession.CLOSED | ClientSession.AUTHED, 0); + + if ((ret & ClientSession.CLOSED) != 0) { + System.err.println("error"); + System.exit(-1); + } + ClientChannel channel = sshSession.createChannel("shell"); + channel.setIn(new StringBufferInputStream(TEST_CONTENT + "\n")); + ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); + channel.setOut(byteOut); + channel.setErr(byteOut); + channel.open(); + try { + Thread.sleep(WAIT_TIME); + } catch (InterruptedException ie) { + // do nothing + } + byte[] output = byteOut.toByteArray(); + Assert.assertEquals("Output not as expected",Integer.toString(TEST_CONTENT), new String(output).trim()); + sshSession.close(true); + } finally { + client.stop(); + } + + command.ssh(new String[] {STOP_COMMAND}); + return; + } + + @Test + public void testSshCommandWithConfigAdminDisabledSsh() throws Exception { + testDisabled(false); + } + + @Test + public void testSshCommandWithConfigAdminDisabledSshByDefault() throws Exception { + testDisabled(true); + } + + private void testDisabled(boolean isDefault) throws Exception { + CommandSession session = EasyMock.createMock(CommandSession.class); + session.put((String)EasyMock.anyObject(), EasyMock.anyObject()); + EasyMock.expectLastCall().times(4); + EasyMock.expect(session.execute(GOGO_SHELL_COMMAND)).andReturn(null); + session.close(); + EasyMock.expectLastCall(); + EasyMock.replay(session); + + CommandProcessor processor = EasyMock.createMock(CommandProcessor.class); + EasyMock.expect(processor.createSession((ConsoleInputStream)EasyMock.anyObject(), (PrintStream)EasyMock.anyObject(), (PrintStream)EasyMock.anyObject())).andReturn(session); + EasyMock.replay(processor); + + final ServiceRegistration<?> registration = EasyMock.createMock(ServiceRegistration.class); + registration.setProperties((Dictionary)EasyMock.anyObject()); + EasyMock.expectLastCall(); + EasyMock.replay(registration); + + BundleContext context = EasyMock.createMock(BundleContext.class); + EasyMock.expect(context.getProperty(USE_CONFIG_ADMIN_PROP)).andReturn(TRUE); + EasyMock.expect(context.getProperty(DEFAULT_USER_STORAGE)).andReturn(TRUE).anyTimes(); + EasyMock.expect( + (ServiceRegistration) context.registerService( + (String)EasyMock.anyObject(), + (ManagedService)EasyMock.anyObject(), + (Dictionary<String, ?>)EasyMock.anyObject()) + ).andAnswer((IAnswer<ServiceRegistration<?>>) new IAnswer<ServiceRegistration<?>>() { + public ServiceRegistration<?> answer() { + configurator = (ManagedService) EasyMock.getCurrentArguments()[1]; + return registration; + } + }); + EasyMock.expect( + context.registerService( + (String)EasyMock.anyObject(), + (SshCommand)EasyMock.anyObject(), + (Dictionary<String, ?>)EasyMock.anyObject())).andReturn(null); + EasyMock.replay(context); + + Map<String, String> environment = new HashMap<String, String>(); + environment.put(TERM_PROPERTY, XTERM); + Environment env = EasyMock.createMock(Environment.class); + EasyMock.expect(env.getEnv()).andReturn(environment); + EasyMock.replay(env); + + SshCommand command = new SshCommand(processor, context); + Dictionary props = new Hashtable(); + props.put("port", SSH_PORT); + props.put("host", HOST); + if (isDefault == false) { + props.put("enabled", FALSE); + } + configurator.updated(props); + + SshClient client = SshClient.setUpDefaultClient(); + client.start(); + try { + ConnectFuture connectFuture = client.connect(HOST, Integer.valueOf(SSH_PORT)); + DefaultConnectFuture defaultConnectFuture = (DefaultConnectFuture) connectFuture; + + try { + Thread.sleep(WAIT_TIME); + } catch (InterruptedException ie) { + // do nothing + } + ClientSession sshSession; + try { + sshSession = defaultConnectFuture.getSession(); + Assert.fail("It should not be possible to connect to " + HOST + ":" + SSH_PORT); + } catch (RuntimeSshException e) { + //this is expected + } + } finally { + client.stop(); + } + + try { + command.ssh(new String[] {STOP_COMMAND}); + } catch (IllegalStateException e) { + // this is expected + } + return; + } + + @After + public void cleanUp() { + clean(); + } + + private void clean() { + System.setProperty(USER_STORE_FILE_NAME, ""); + File file = new File(STORE_FILE_NAME); + if (file.exists()) { + file.delete(); + } + + System.setProperty(JAAS_CONFIG_PROPERTY_NAME, ""); + File jaasConfFile = new File(JAAS_CONFIG_FILE_NAME); + if (jaasConfFile.exists()) { + jaasConfFile.delete(); + } + } + + private void initStore() throws Exception { + System.setProperty(USER_STORE_FILE_NAME, STORE_FILE_NAME); + SecureUserStore.initStorage(); + SecureUserStore.putUser(USERNAME, DigestUtil.encrypt(PASSWORD), null); + } + + private void initJaasConfigFile() throws Exception { + System.setProperty(JAAS_CONFIG_PROPERTY_NAME, JAAS_CONFIG_FILE_NAME); + File jaasConfFile = new File(JAAS_CONFIG_FILE_NAME); + if (!jaasConfFile.exists()) { + PrintWriter out = null; + try { + out = new PrintWriter(jaasConfFile); + out.println("equinox_console {"); + out.println(" org.eclipse.equinox.console.jaas.SecureStorageLoginModule REQUIRED;"); + out.println("};"); + } finally { + if (out != null) { + out.close(); + } + } + } + } + +} diff --git a/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/ssh/SshDisconnectCommandTests.java b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/ssh/SshDisconnectCommandTests.java new file mode 100755 index 000000000..8ab10b244 --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/ssh/SshDisconnectCommandTests.java @@ -0,0 +1,234 @@ +package org.eclipse.equinox.console.ssh; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.StringBufferInputStream; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.Dictionary; +import java.util.HashMap; +import java.util.Map; + +import org.apache.felix.service.command.CommandProcessor; +import org.apache.felix.service.command.CommandSession; +import org.apache.sshd.ClientChannel; +import org.apache.sshd.ClientSession; +import org.apache.sshd.SshClient; +import org.apache.sshd.client.future.ConnectFuture; +import org.apache.sshd.client.future.DefaultConnectFuture; +import org.apache.sshd.server.Environment; +import org.easymock.EasyMock; +import org.easymock.IAnswer; +import org.eclipse.equinox.console.commands.DisconnectCommand; +import org.eclipse.equinox.console.common.ConsoleInputStream; +import org.eclipse.equinox.console.storage.DigestUtil; +import org.eclipse.equinox.console.storage.SecureUserStore; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.osgi.framework.BundleContext; + +public class SshDisconnectCommandTests { + private static final int TEST_CONTENT = 100; + private static final String USER_STORE_FILE_NAME = "org.eclipse.equinox.console.jaas.file"; + private static final String JAAS_CONFIG_FILE_NAME = "jaas.config"; + private static final String JAAS_CONFIG_PROPERTY_NAME = "java.security.auth.login.config"; + private static final String DEFAULT_USER_STORAGE = "osgi.console.ssh.useDefaultSecureStorage"; + private static final String USE_CONFIG_ADMIN_PROP = "osgi.console.useConfigAdmin"; + private static final String SSH_PORT_PROP_NAME = "osgi.console.ssh"; + private static final String STORE_FILE_NAME = SshCommandTests.class.getName() + "_store"; + private static final String GOGO_SHELL_COMMAND = "gosh --login --noshutdown"; + private static final String TRUE = "true"; + private static final String FALSE = "false"; + private static final String USERNAME = "username"; + private static final String PASSWORD = "password"; + private static final String START_COMMAND = "start"; + private static final String STOP_COMMAND = "stop"; + private static final String TERM_PROPERTY = "TERM"; + private static final String XTERM = "XTERM"; + private static final String HOST = "localhost"; + private static final int SSH_PORT = 2222; + private static final long WAIT_TIME = 5000; + private SshSession sshSession; + private InputStream in; + + @Before + public void init() throws Exception { + clean(); + initStore(); + initJaasConfigFile(); + } + + @Test + public void testSshCommand() throws Exception { + final CommandSession session = EasyMock.createMock(CommandSession.class); + EasyMock.makeThreadSafe(session, true); + session.put((String)EasyMock.anyObject(), EasyMock.anyObject()); + EasyMock.expectLastCall(); + session.put((String)EasyMock.anyObject(), EasyMock.anyObject()); + EasyMock.expectLastCall(); + session.put((String)EasyMock.anyObject(), EasyMock.anyObject()); + EasyMock.expectLastCall(); + session.put((String)EasyMock.anyObject(), EasyMock.anyObject()); + EasyMock.expectLastCall(); + session.put((String)EasyMock.anyObject(), EasyMock.anyObject()); + EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() { + + @Override + public Object answer() throws Throwable { + sshSession = (SshSession)EasyMock.getCurrentArguments()[1]; + return null; + } + + }); + EasyMock.expect(session.execute(GOGO_SHELL_COMMAND)).andReturn(null); + EasyMock.expect(session.get("CLOSEABLE")).andReturn(sshSession); + session.close(); + EasyMock.expectLastCall().atLeastOnce(); + EasyMock.replay(session); + + CommandProcessor processor = EasyMock.createMock(CommandProcessor.class); + EasyMock.expect(processor.createSession((ConsoleInputStream)EasyMock.anyObject(), (PrintStream)EasyMock.anyObject(), (PrintStream)EasyMock.anyObject())).andReturn(session); + EasyMock.replay(processor); + + BundleContext context = EasyMock.createMock(BundleContext.class); + EasyMock.makeThreadSafe(context, true); + EasyMock.expect(context.getProperty(USE_CONFIG_ADMIN_PROP)).andReturn(FALSE); + EasyMock.expect(context.getProperty(DEFAULT_USER_STORAGE)).andReturn(TRUE).anyTimes(); + EasyMock.expect(context.getProperty(SSH_PORT_PROP_NAME)).andReturn(Integer.toString(SSH_PORT)); + EasyMock.expect(context.registerService((String)EasyMock.anyObject(), EasyMock.anyObject(), (Dictionary<String, ?>)EasyMock.anyObject())).andReturn(null); + EasyMock.replay(context); + + Map<String, String> environment = new HashMap<String, String>(); + environment.put(TERM_PROPERTY, XTERM); + Environment env = EasyMock.createMock(Environment.class); + EasyMock.expect(env.getEnv()).andReturn(environment); + EasyMock.replay(env); + + SshCommand command = new SshCommand(processor, context); + command.ssh(new String[] {START_COMMAND}); + + SshClient client = SshClient.setUpDefaultClient(); + client.start(); + try { + ConnectFuture connectFuture = client.connect(HOST, SSH_PORT); + DefaultConnectFuture defaultConnectFuture = (DefaultConnectFuture) connectFuture; + + try { + Thread.sleep(WAIT_TIME); + } catch (InterruptedException ie) { + // do nothing + } + ClientSession sshSession = defaultConnectFuture.getSession(); + + int ret = ClientSession.WAIT_AUTH; + sshSession.authPassword(USERNAME, PASSWORD); + ret = sshSession.waitFor(ClientSession.WAIT_AUTH | ClientSession.CLOSED | ClientSession.AUTHED, 0); + + if ((ret & ClientSession.CLOSED) != 0) { + System.err.println("error"); + System.exit(-1); + } + ClientChannel channel = sshSession.createChannel("shell"); + + PipedOutputStream outputStream = new PipedOutputStream(); + PipedInputStream inputStream = new PipedInputStream(outputStream); + + final DisconnectCommand disconnectCommand = new DisconnectCommand(context); + in = System.in; + System.setIn(inputStream); + + ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); + channel.setIn(new StringBufferInputStream(TEST_CONTENT + "\n")); + channel.setOut(byteOut); + channel.setErr(byteOut); + channel.open(); + + + new Thread() { + public void run() { + disconnectCommand.disconnect(session); + } + }.start(); + + outputStream.write(new byte[]{'y'}); + outputStream.write('\n'); + outputStream.flush(); + + Thread.sleep(WAIT_TIME); + + try { + Thread.sleep(WAIT_TIME); + } catch (InterruptedException ie) { + // do nothing + } + + try { + outputStream.write(TEST_CONTENT); + outputStream.write('\n'); + outputStream.flush(); + Assert.fail("Connection not closed"); + } catch (Exception e) { + // we should be here + } + sshSession.close(true); + } finally { + client.stop(); + } + + command.ssh(new String[] {STOP_COMMAND}); + return; + } + + @After + public void cleanUp() { + clean(); + } + + private void clean() { + System.setProperty(USER_STORE_FILE_NAME, ""); + File file = new File(STORE_FILE_NAME); + if (file.exists()) { + file.delete(); + } + + System.setProperty(JAAS_CONFIG_PROPERTY_NAME, ""); + File jaasConfFile = new File(JAAS_CONFIG_FILE_NAME); + if (jaasConfFile.exists()) { + jaasConfFile.delete(); + } + + System.setIn(in); + } + + private void initStore() throws Exception { + System.setProperty(USER_STORE_FILE_NAME, STORE_FILE_NAME); + SecureUserStore.initStorage(); + SecureUserStore.putUser(USERNAME, DigestUtil.encrypt(PASSWORD), null); + } + + private void initJaasConfigFile() throws Exception { + System.setProperty(JAAS_CONFIG_PROPERTY_NAME, JAAS_CONFIG_FILE_NAME); + File jaasConfFile = new File(JAAS_CONFIG_FILE_NAME); + if (!jaasConfFile.exists()) { + PrintWriter out = null; + try { + out = new PrintWriter(jaasConfFile); + out.println("equinox_console {"); + out.println(" org.eclipse.equinox.console.jaas.SecureStorageLoginModule REQUIRED;"); + out.println("};"); + } finally { + if (out != null) { + out.close(); + } + } + } + } +} diff --git a/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/ssh/SshInputHandlerTests.java b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/ssh/SshInputHandlerTests.java new file mode 100755 index 000000000..e7ed407a0 --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/ssh/SshInputHandlerTests.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2011 SAP AG + * 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: + * Lazar Kirchev, SAP AG - initial API and implementation + *******************************************************************************/ + +package org.eclipse.equinox.console.ssh; + +import java.io.ByteArrayOutputStream; +import java.io.StringBufferInputStream; + +import org.eclipse.equinox.console.common.ConsoleInputStream; +import org.eclipse.equinox.console.common.ConsoleOutputStream; +import org.eclipse.equinox.console.ssh.SshInputHandler; +import org.junit.Assert; +import org.junit.Test; + + +public class SshInputHandlerTests { + + private static final long WAIT_TIME = 10000; + + @Test + public void testHandler() throws Exception { + StringBufferInputStream input = new StringBufferInputStream("abcde"); + ConsoleInputStream in = new ConsoleInputStream(); + ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); + ConsoleOutputStream out = new ConsoleOutputStream(byteOut); + SshInputHandler handler = new SshInputHandler(input, in, out); + handler.start(); + + // wait for the accept thread to start execution + try { + Thread.sleep(WAIT_TIME); + } catch (InterruptedException ie) { + // do nothing + } + + String res = byteOut.toString(); + Assert.assertTrue("Wrong input. Expected abcde, read " + res, res.equals("abcde")); + } +} diff --git a/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/ssh/SshInputScannerTests.java b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/ssh/SshInputScannerTests.java new file mode 100755 index 000000000..5f246fbdc --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/ssh/SshInputScannerTests.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2011 SAP AG + * 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: + * Lazar Kirchev, SAP AG - initial API and implementation + *******************************************************************************/ + +package org.eclipse.equinox.console.ssh; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import org.eclipse.equinox.console.common.ConsoleInputStream; +import org.eclipse.equinox.console.common.ConsoleOutputStream; +import org.junit.Assert; +import org.junit.Test; + + +public class SshInputScannerTests { + + private static final byte ESC = 27; + + @Test + public void testScan() throws Exception { + ConsoleInputStream in = new ConsoleInputStream(); + ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); + ConsoleOutputStream out = new ConsoleOutputStream(byteOut); + SshInputScanner scanner = new SshInputScanner(in, out); + try { + scanner.scan((byte) 'a'); + scanner.scan((byte) 'b'); + scanner.scan((byte) 'c'); + } catch (IOException e) { + System.out.println("Error while scanning: " + e.getMessage()); + e.printStackTrace(); + throw e; + } + + String output = byteOut.toString(); + Assert.assertTrue("Output incorrect. Expected abc, but read " + output, output.equals("abc")); + } + + @Test + public void testScanESC() throws Exception { + ConsoleInputStream in = new ConsoleInputStream(); + ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); + ConsoleOutputStream out = new ConsoleOutputStream(byteOut); + SshInputScanner scanner = new SshInputScanner(in, out); + + try { + scanner.scan((byte) 'a'); + scanner.scan((byte) ESC); + scanner.scan((byte) 'b'); + } catch (IOException e) { + System.out.println("Error while scanning: " + e.getMessage()); + e.printStackTrace(); + throw e; + } + + String output = byteOut.toString(); + Assert.assertTrue("Output incorrect. Expected ab, but read " + output, output.equals("ab")); + } +} diff --git a/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/ssh/SshShellTests.java b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/ssh/SshShellTests.java new file mode 100755 index 000000000..9c041fdf0 --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/ssh/SshShellTests.java @@ -0,0 +1,152 @@ +/******************************************************************************* + * Copyright (c) 2011 SAP AG + * 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: + * Lazar Kirchev, SAP AG - initial API and implementation + *******************************************************************************/ + +package org.eclipse.equinox.console.ssh; + +import java.io.File; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintStream; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.felix.service.command.CommandProcessor; +import org.apache.felix.service.command.CommandSession; +import org.apache.sshd.server.Environment; +import org.easymock.EasyMock; +import org.eclipse.equinox.console.common.ConsoleInputStream; +import org.eclipse.equinox.console.storage.DigestUtil; +import org.eclipse.equinox.console.storage.SecureUserStore; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.osgi.framework.BundleContext; + + +public class SshShellTests { + + private static final int TEST_CONTENT = 100; + private static final String USER_STORE_FILE_NAME = "org.eclipse.equinox.console.jaas.file"; + private static final String DEFAULT_USER_STORAGE = "osgi.console.ssh.useDefaultSecureStorage"; + private static final String USER_STORE_NAME = SshShellTests.class.getName() + "_store"; + private static final String HOST = "localhost"; + private static final String GOGO_SHELL_COMMAND = "gosh --login --noshutdown"; + private static final String TERM_PROPERTY = "TERM"; + private static final String XTERM = "XTERM"; + private static final String USERNAME = "username"; + private static final String PASSWORD = "password"; + private static final String TRUE = "true"; + + @Before + public void init() throws Exception { + clean(); + initStore(); + } + + @Test + public void testSshConnection() throws Exception { + ServerSocket servSocket = null; + Socket socketClient = null; + Socket socketServer = null; + SshShell shell = null; + OutputStream outClient = null; + OutputStream outServer = null; + + try { + + servSocket = new ServerSocket(0); + socketClient = new Socket(HOST, servSocket.getLocalPort()); + socketServer = servSocket.accept(); + + CommandSession session = EasyMock.createMock(CommandSession.class); + EasyMock.makeThreadSafe(session, true); + session.put((String)EasyMock.anyObject(), EasyMock.anyObject()); + EasyMock.expectLastCall().times(5); + EasyMock.expect(session.execute(GOGO_SHELL_COMMAND)).andReturn(null); + session.close(); + EasyMock.expectLastCall(); + EasyMock.replay(session); + + CommandProcessor processor = EasyMock.createMock(CommandProcessor.class); + EasyMock.expect(processor.createSession((ConsoleInputStream)EasyMock.anyObject(), (PrintStream)EasyMock.anyObject(), (PrintStream)EasyMock.anyObject())).andReturn(session); + EasyMock.replay(processor); + + BundleContext context = EasyMock.createMock(BundleContext.class); + EasyMock.makeThreadSafe(context, true); + EasyMock.expect(context.getProperty(DEFAULT_USER_STORAGE)).andReturn(TRUE); + EasyMock.replay(context); + + Map<String, String> environment = new HashMap<String, String>(); + environment.put(TERM_PROPERTY, XTERM); + Environment env = EasyMock.createMock(Environment.class); + EasyMock.expect(env.getEnv()).andReturn(environment); + EasyMock.replay(env); + + List<CommandProcessor> processors = new ArrayList<CommandProcessor>(); + processors.add(processor); + shell = new SshShell(processors, context); + shell.setInputStream(socketServer.getInputStream()); + shell.setOutputStream(socketServer.getOutputStream()); + shell.start(env); + + outClient = socketClient.getOutputStream(); + outClient.write(TEST_CONTENT); + outClient.write('\n'); + outClient.flush(); + InputStream input = socketClient.getInputStream(); + int in = input.read(); + Assert.assertTrue("Server received [" + in + "] instead of " + TEST_CONTENT + " from the ssh client.", in == TEST_CONTENT); + } finally { + if (socketClient != null) { + socketClient.close(); + } + if (outClient != null) { + outClient.close(); + } + if (outServer != null) { + outServer.close(); + } + + if (socketServer != null) { + socketServer.close(); + } + + if (servSocket != null) { + servSocket.close(); + } + + } + } + + @After + public void cleanUp() { + clean(); + } + + private void initStore() throws Exception { + System.setProperty(USER_STORE_FILE_NAME, USER_STORE_NAME); + SecureUserStore.initStorage(); + SecureUserStore.putUser(USERNAME, DigestUtil.encrypt(PASSWORD), null); + } + + private void clean() { + System.setProperty(USER_STORE_FILE_NAME, ""); + File file = new File(USER_STORE_NAME); + if(file.exists()) { + file.delete(); + } + } +} diff --git a/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/ssh/UserAdminCommandTests.java b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/ssh/UserAdminCommandTests.java new file mode 100755 index 000000000..658690178 --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/ssh/UserAdminCommandTests.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright (c) 2011 SAP AG + * 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: + * Lazar Kirchev, SAP AG - initial API and implementation + *******************************************************************************/ + +package org.eclipse.equinox.console.ssh; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.util.HashSet; +import java.util.Set; + +import org.apache.felix.service.command.CommandSession; +import org.easymock.EasyMock; +import org.eclipse.equinox.console.storage.DigestUtil; +import org.eclipse.equinox.console.storage.SecureUserStore; +import org.junit.After; +import org.junit.Test; + + +public class UserAdminCommandTests { + + private static final String USER_STORE_FILE_NAME_PROPERTY = "org.eclipse.equinox.console.jaas.file"; + private static final String USER_STORE_FILE_NAME = UserAdminCommandTests.class.getName() + "_store"; + private static final String USERNAME_OPTION = "-username"; + private static final String PASSWORD_OPTION = "-password"; + private static final String ROLES_OPTION = "-roles"; + private static final String USERNAME1 = "username1"; + private static final String USERNAME2 = "username2"; + private static final String PASSWORD1 = "password1"; + private static final String PASSWORD2 = "password2"; + private static final String ROLES1 = "role1,role2"; + private static final String ROLES2 = "role3,role4"; + private static final String ROLES_TO_REMOVE = "role2"; + private static final String REMAINING_ROLES = "role1"; + + @Test + public void testCommand() throws Exception { + cleanUp(); + + System.setProperty(USER_STORE_FILE_NAME_PROPERTY, USER_STORE_FILE_NAME); + SecureUserStore.initStorage(); + + CommandSession session = EasyMock.createMock(CommandSession.class); + session.put((String)EasyMock.anyObject(), EasyMock.anyObject()); + EasyMock.expectLastCall().times(3); + EasyMock.replay(session); + + UserAdminCommand command = new UserAdminCommand(); + command.addUser(new String[] {USERNAME_OPTION, USERNAME1, PASSWORD_OPTION, PASSWORD1}); + command.addUser(new String[] {USERNAME_OPTION, USERNAME2, PASSWORD_OPTION, PASSWORD2, ROLES_OPTION, ROLES2}); + + String[] usernames = SecureUserStore.getUserNames(); + boolean arePresent = (usernames[0].equals(USERNAME1) || usernames[0].equals(USERNAME2)) && (usernames[1].equals(USERNAME1) || usernames[1].equals(USERNAME2)) && (!usernames[0].equals(usernames[1])); + assertTrue("Usernames not correctly saved", arePresent); + + String pass1 = SecureUserStore.getPassword(USERNAME1); + String pass2 = SecureUserStore.getPassword(USERNAME2); + assertTrue("Passwords not correctly saved", pass1.equals(DigestUtil.encrypt(PASSWORD1)) && pass2.equals(DigestUtil.encrypt(PASSWORD2))); + + String roles = SecureUserStore.getRoles(USERNAME2); + assertEquals("Roles for the second user are not as expected", ROLES2, roles); + + command.addRoles(new String[] {USERNAME_OPTION, USERNAME1, ROLES_OPTION, ROLES1}); + roles = SecureUserStore.getRoles(USERNAME1); + boolean areRolesEqual = compareRoles(ROLES1, roles); + assertTrue("Roles for the first user are not as expected", areRolesEqual); + + command.removeRoles(new String[] {USERNAME_OPTION, USERNAME1, ROLES_OPTION, ROLES_TO_REMOVE}); + roles = SecureUserStore.getRoles(USERNAME1); + areRolesEqual = compareRoles(REMAINING_ROLES, roles); + assertTrue("Roles for the first user are not as expected", areRolesEqual); + + command.resetPassword(USERNAME1); + String pass = SecureUserStore.getPassword(USERNAME1); + assertNull("Password should be null", pass); + + command.setPassword(new String[] {USERNAME_OPTION, USERNAME1, PASSWORD_OPTION, PASSWORD1}); + pass = SecureUserStore.getPassword(USERNAME1); + assertEquals("Password should be null", DigestUtil.encrypt(PASSWORD1), pass); + + command.deleteUser(USERNAME2); + assertFalse("User2 should not exist", SecureUserStore.existsUser(USERNAME2)); + } + + @After + public void cleanUp() { + System.setProperty(USER_STORE_FILE_NAME_PROPERTY, ""); + File file = new File(USER_STORE_FILE_NAME); + if(file.exists()) { + file.delete(); + } + } + + private boolean compareRoles(String expectedRoles, String actualRoles) { + Set<String> expectedRolesSet = new HashSet<String>(); + for(String role : expectedRoles.split(",")) { + expectedRolesSet.add(role); + } + + Set<String> actualRolesSet = new HashSet<String>(); + for(String role : actualRoles.split(",")) { + actualRolesSet.add(role); + } + + return expectedRolesSet.equals(actualRolesSet); + } + +} diff --git a/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/storage/DigestUtilTests.java b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/storage/DigestUtilTests.java new file mode 100755 index 000000000..d1a040b30 --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/storage/DigestUtilTests.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2011 SAP AG + * 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: + * Lazar Kirchev, SAP AG - initial API and implementation + *******************************************************************************/ + +package org.eclipse.equinox.console.storage; + +import static org.junit.Assert.*; +import java.security.MessageDigest; + +import org.junit.Test; + + +public class DigestUtilTests { + + private static final char[] HEX_CHARS = "0123456789abcdef".toCharArray(); + private static final String MD5 = "MD5"; + private static final String SHA1 = "SHA1"; + private static final String TEXT = "sometext"; + + @Test + public void testEncrypt() throws Exception { + MessageDigest md = MessageDigest.getInstance(MD5); + md.update(TEXT.getBytes()); + byte[] digest = md.digest(); + + char[] chars = new char[2 * digest.length]; + for (int i = 0; i < digest.length; ++i) + { + chars[2 * i] = HEX_CHARS[(digest[i] & 0xF0) >>> 4]; + chars[2 * i + 1] = HEX_CHARS[digest[i] & 0x0F]; + } + + String modifiedText = TEXT + new String(chars); + md = MessageDigest.getInstance(SHA1); + md.update(modifiedText.getBytes()); + digest = md.digest(); + + chars = new char[2 * digest.length]; + for (int i = 0; i < digest.length; ++i) + { + chars[2 * i] = HEX_CHARS[(digest[i] & 0xF0) >>> 4]; + chars[2 * i + 1] = HEX_CHARS[digest[i] & 0x0F]; + } + + String expectedEncryptedText = new String(chars); + + assertEquals("Encrypted text not as expected", expectedEncryptedText, DigestUtil.encrypt(TEXT)); + } +} diff --git a/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/storage/SecureUserStoreTests.java b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/storage/SecureUserStoreTests.java new file mode 100755 index 000000000..20062e17b --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/storage/SecureUserStoreTests.java @@ -0,0 +1,109 @@ +/******************************************************************************* + * Copyright (c) 2011 SAP AG + * 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: + * Lazar Kirchev, SAP AG - initial API and implementation + *******************************************************************************/ + +package org.eclipse.equinox.console.storage; + +import static org.junit.Assert.*; + +import java.io.File; +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.equinox.console.jaas.SecureStorageLoginModule; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class SecureUserStoreTests { + + private static final String USER_STORE_FILE_NAME_PROPERTY = "org.eclipse.equinox.console.jaas.file"; + private static final String USER_STORE_FILE_NAME = SecureUserStoreTests.class.getName() + "_store"; + private static final String USERNAME1 = "username1"; + private static final String USERNAME2 = "username2"; + private static final String PASSWORD1 = "password1"; + private static final String PASSWORD2 = "password2"; + private static final String ROLES1 = "role1,role2"; + private static final String ROLES2 = "role3,role4"; + private static final String ROLES_TO_REMOVE = "role2"; + private static final String REMAINING_ROLES = "role1"; + + @Test + public void testStore() throws Exception { + cleanUp(); + + System.setProperty(USER_STORE_FILE_NAME_PROPERTY, USER_STORE_FILE_NAME); + + SecureUserStore.initStorage(); + assertTrue("Secure store file does not exist", new File(USER_STORE_FILE_NAME).exists()); + + SecureUserStore.putUser(USERNAME1, PASSWORD1, null); + SecureUserStore.putUser(USERNAME2, PASSWORD2, ROLES2); + + String[] usernames = SecureUserStore.getUserNames(); + boolean arePresent = (usernames[0].equals(USERNAME1) || usernames[0].equals(USERNAME2)) && (usernames[1].equals(USERNAME1) || usernames[1].equals(USERNAME2)) && (!usernames[0].equals(usernames[1])); + assertTrue("Usernames not correctly saved", arePresent); + + String pass1 = SecureUserStore.getPassword(USERNAME1); + String pass2 = SecureUserStore.getPassword(USERNAME2); + assertTrue("Passwords not correctly saved", pass1.equals(PASSWORD1) && pass2.equals(PASSWORD2)); + + boolean existsUser1 = SecureUserStore.existsUser(USERNAME1); + boolean existsUser2 = SecureUserStore.existsUser(USERNAME2); + assertTrue("Users should exist", existsUser1 && existsUser2); + + String roles = SecureUserStore.getRoles(USERNAME2); + assertEquals("Roles for the second user are not as expected", ROLES2, roles); + + SecureUserStore.addRoles(USERNAME1, ROLES1); + roles = SecureUserStore.getRoles(USERNAME1); + boolean areRolesEqual = compareRoles(ROLES1, roles); + assertTrue("Roles for the first user are not as expected", areRolesEqual); + + SecureUserStore.removeRoles(USERNAME1, ROLES_TO_REMOVE); + roles = SecureUserStore.getRoles(USERNAME1); + areRolesEqual = compareRoles(REMAINING_ROLES, roles); + assertTrue("Roles for the first user are not as expected", areRolesEqual); + + SecureUserStore.resetPassword(USERNAME1); + String pass = SecureUserStore.getPassword(USERNAME1); + assertNull("Password should be null", pass); + + SecureUserStore.setPassword(USERNAME1, PASSWORD1); + pass = SecureUserStore.getPassword(USERNAME1); + assertEquals("Password should be null", PASSWORD1, pass); + + SecureUserStore.deleteUser(USERNAME2); + assertFalse("User2 should not exist", SecureUserStore.existsUser(USERNAME2)); + } + + @After + public void cleanUp() { + System.setProperty(USER_STORE_FILE_NAME_PROPERTY, ""); + File file = new File(USER_STORE_FILE_NAME); + if(file.exists()) { + file.delete(); + } + } + + private boolean compareRoles(String expectedRoles, String actualRoles) { + Set<String> expectedRolesSet = new HashSet<String>(); + for(String role : expectedRoles.split(",")) { + expectedRolesSet.add(role); + } + + Set<String> actualRolesSet = new HashSet<String>(); + for(String role : actualRoles.split(",")) { + actualRolesSet.add(role); + } + + return expectedRolesSet.equals(actualRolesSet); + } +} diff --git a/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/supportability/ConsoleInputHandlerTests.java b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/supportability/ConsoleInputHandlerTests.java new file mode 100755 index 000000000..ad4599070 --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/supportability/ConsoleInputHandlerTests.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2011 SAP AG + * 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: + * Lazar Kirchev, SAP AG - initial contribution + ******************************************************************************/ + +package org.eclipse.equinox.console.supportability; + +import org.eclipse.equinox.console.common.ConsoleInputStream; +import org.junit.Assert; +import org.junit.Test; + +import java.io.ByteArrayOutputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; + +public class ConsoleInputHandlerTests { + + private static final long WAIT_TIME = 10000; + + @Test + public void testHandler() throws Exception { + PipedInputStream input = new PipedInputStream(); + PipedOutputStream output = new PipedOutputStream(input); + ConsoleInputStream in = new ConsoleInputStream(); + ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); + ConsoleInputHandler handler = new ConsoleInputHandler(input, in, byteOut); + byte[] testInput = new byte[] { 'a', 'b', 'c', 'd', 'e', '\r', '\n' }; + byte[] expected = new byte[] { 'a', 'b', 'c', 'd', 'e', '\n' }; + output.write(testInput); + output.flush(); + handler.start(); + + try { + Thread.sleep(WAIT_TIME); + } catch (Exception e) { + // do nothing + } + + byte[] read = new byte[expected.length]; + in.read(read, 0, expected.length); + for (int i = 0; i < expected.length; i++) { + Assert.assertEquals("Incorrect char read. Position " + i + ", expected " + expected[i] + ", read " + read[i], expected[i], read[i]); + } + + output.close(); + input.close(); + } + +} diff --git a/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/supportability/ConsoleInputScannerTests.java b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/supportability/ConsoleInputScannerTests.java new file mode 100755 index 000000000..2240e2c65 --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/supportability/ConsoleInputScannerTests.java @@ -0,0 +1,257 @@ +/******************************************************************************* + * Copyright (c) 2011 SAP AG + * 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: + * Lazar Kirchev, SAP AG - initial contribution + ******************************************************************************/ + +package org.eclipse.equinox.console.supportability; + +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; + +import org.apache.felix.service.command.CommandSession; +import org.eclipse.equinox.console.common.ConsoleInputStream; +import org.eclipse.equinox.console.common.ConsoleOutputStream; +import org.eclipse.equinox.console.common.KEYS; +import org.eclipse.equinox.console.common.terminal.ANSITerminalTypeMappings; +import org.eclipse.equinox.console.common.terminal.SCOTerminalTypeMappings; +import org.eclipse.equinox.console.common.terminal.TerminalTypeMappings; +import org.eclipse.equinox.console.common.terminal.VT100TerminalTypeMappings; +import org.eclipse.equinox.console.common.terminal.VT220TerminalTypeMappings; +import org.eclipse.equinox.console.common.terminal.VT320TerminalTypeMappings; +import org.eclipse.equinox.console.completion.common.Completer; +import org.junit.Assert; +import org.junit.Test; +import org.osgi.framework.BundleContext; + +import java.io.ByteArrayOutputStream; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +public class ConsoleInputScannerTests { + + private static int BS; + + private static final int LF = 10; + + private static final int CR = 13; + + private static final int ESC = 27; + + private static int DELL; + + private static int TAB = 9; + + private static final String COMMANDS = ".commands"; + + @Test + public void test() throws Exception { + Set<TerminalTypeMappings> supportedEscapeSequences = new HashSet<TerminalTypeMappings>(); + supportedEscapeSequences.add(new ANSITerminalTypeMappings()); + supportedEscapeSequences.add(new VT100TerminalTypeMappings()); + supportedEscapeSequences.add(new VT220TerminalTypeMappings()); + supportedEscapeSequences.add(new VT320TerminalTypeMappings()); + supportedEscapeSequences.add(new SCOTerminalTypeMappings()); + + for (TerminalTypeMappings ttMappings : supportedEscapeSequences) { + Map<String, KEYS> escapesToKey = ttMappings.getEscapesToKey(); + Map<KEYS, byte[]> keysToEscapes = new HashMap<KEYS, byte[]>(); + for (Entry<String, KEYS> entry : escapesToKey.entrySet()) { + keysToEscapes.put(entry.getValue(), entry.getKey().getBytes()); + } + + BS = ttMappings.getBackspace(); + DELL = ttMappings.getDel(); + + testScan(ttMappings, keysToEscapes); + } + } + + private void testScan(TerminalTypeMappings mappings, Map<KEYS, byte[]> keysToEscapes) throws Exception { + ConsoleInputStream in = new ConsoleInputStream(); + ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); + ConsoleOutputStream out = new ConsoleOutputStream(byteOut); + ConsoleInputScanner scanner = new ConsoleInputScanner(in, out); + scanner.setBackspace(mappings.getBackspace()); + scanner.setCurrentEscapesToKey(mappings.getEscapesToKey()); + scanner.setDel(mappings.getDel()); + scanner.setEscapes(mappings.getEscapes()); + + byte[] line1 = new byte[] { 'a', 'b', 'c', 'd', 'e' }; + byte[] line2 = new byte[] { 't', 'e', 's', 't' }; + byte[] line3 = new byte[] { 'l', 'a', 's', 't' }; + + addLine(scanner, line1); + checkInpusStream(in, line1); + + addLine(scanner, line2); + checkInpusStream(in, line2); + + addLine(scanner, line3); + checkInpusStream(in, line3); + + add(scanner, keysToEscapes.get(KEYS.UP)); + add(scanner, keysToEscapes.get(KEYS.UP)); + String res = byteOut.toString(); + Assert.assertTrue("Error processing up arrow; expected test, actual " + res.substring(res.length() - 4), res.endsWith("test")); + + add(scanner, keysToEscapes.get(KEYS.DOWN)); + res = byteOut.toString(); + Assert.assertTrue("Error processing down arrow; expected last, actual " + res.substring(res.length() - 4), res.endsWith("last")); + + add(scanner, keysToEscapes.get(KEYS.PGUP)); + res = byteOut.toString(); + Assert.assertTrue("Error processing PageUp; expected abcde, actual " + res.substring(res.length() - 4), res.endsWith("abcde")); + + add(scanner, keysToEscapes.get(KEYS.PGDN)); + res = byteOut.toString(); + Assert.assertTrue("Error processing PageDown; expected last, actual " + res.substring(res.length() - 4), res.endsWith("last")); + + if (BS > 0) { + scanner.scan(BS); + res = byteOut.toString(); + Assert.assertTrue("Error processing backspace; expected las, actual " + res.substring(res.length() - 3), res.endsWith("las")); + scanner.scan('t'); + } + + if (DELL > 0) { + add(scanner, keysToEscapes.get(KEYS.LEFT)); + scanner.scan(DELL); + res = byteOut.toString(); + Assert.assertTrue("Error processing del; expected las, actual " + res.substring(res.length() - 3), res.endsWith("las")); + scanner.scan('t'); + } + + add(scanner, keysToEscapes.get(KEYS.LEFT)); + add(scanner, keysToEscapes.get(KEYS.LEFT)); + add(scanner, keysToEscapes.get(KEYS.RIGHT)); + if (DELL > 0) { + scanner.scan(DELL); + } else { + add(scanner, keysToEscapes.get(KEYS.DEL)); + } + res = byteOut.toString(); + Assert.assertTrue("Error processing arrows; expected las, actual " + res.substring(res.length() - 3), res.endsWith("las")); + scanner.scan('t'); + + if (keysToEscapes.get(KEYS.DEL) != null) { + add(scanner, keysToEscapes.get(KEYS.LEFT)); + add(scanner, keysToEscapes.get(KEYS.DEL)); + res = byteOut.toString(); + Assert.assertTrue("Error processing delete; expected las, actual " + res.substring(res.length() - 3), res.endsWith("las")); + scanner.scan('t'); + } + + add(scanner, keysToEscapes.get(KEYS.HOME)); + if (DELL > 0) { + scanner.scan(DELL); + } else { + add(scanner, keysToEscapes.get(KEYS.DEL)); + } + res = byteOut.toString(); + res = res.substring(res.length() - 6, res.length() - 3); + Assert.assertTrue("Error processing Home; expected ast, actual " + res, res.equals("ast")); + scanner.scan('l'); + + add(scanner, keysToEscapes.get(KEYS.END)); + add(scanner, keysToEscapes.get(KEYS.LEFT)); + if (DELL > 0) { + scanner.scan(DELL); + } else { + add(scanner, keysToEscapes.get(KEYS.DEL)); + } + res = byteOut.toString(); + Assert.assertTrue("Error processing End; expected las, actual " + res.substring(res.length() - 3), res.endsWith("las")); + scanner.scan('t'); + + add(scanner, keysToEscapes.get(KEYS.LEFT)); + add(scanner, keysToEscapes.get(KEYS.INS)); + scanner.scan('a'); + res = byteOut.toString(); + Assert.assertTrue("Error processing Ins; expected las, actual " + res.substring(res.length() - 4), res.endsWith("lasa")); + + BundleContext context = createMock(BundleContext.class); + expect(context.getServiceReferences(Completer.class.getName(), null)).andReturn(null).anyTimes(); + replay(context); + + Set<String> commands = new HashSet<String>(); + commands.add("equinox:bundles"); + commands.add("equinox:bundle"); + commands.add("gogo:bundlebylocation"); + commands.add("gogo:bundlelevel"); + commands.add("equinox:headers"); + + CommandSession session = createMock(CommandSession.class); + expect(session.get(COMMANDS)).andReturn(commands).anyTimes(); + replay(session); + + scanner.setContext(context); + scanner.setSession(session); + + scanner.scan(CR); + scanner.scan(LF); + scanner.scan('b'); + scanner.scan('u'); + scanner.scan('n'); + scanner.scan(TAB); + res = byteOut.toString(); + Assert.assertTrue("Expected completion suggestion is not contained in the output", res.contains("bundles\r\n")); + Assert.assertTrue("Expected completion suggestion is not contained in the output", res.contains("bundle\r\n")); + Assert.assertTrue("bun should be completed to bundle", res.endsWith("bundle")); + Assert.assertTrue("Expected completion suggestion is not contained in the output", res.contains("bundlebylocation\r\n")); + Assert.assertTrue("Expected completion suggestion is not contained in the output", res.contains("bundlelevel\r\n")); + Assert.assertFalse("Not expected completion suggestion", res.contains("headers\r\n")); + } + + private static void addLine(ConsoleInputScanner scanner, byte[] line) throws Exception { + for (byte b : line) { + try { + scanner.scan(b); + } catch (Exception e) { + System.out.println("Error scanning symbol " + b); + throw new Exception("Error scanning symbol" + b); + } + } + + try { + scanner.scan(CR); + } catch (Exception e) { + System.out.println("Error scanning symbol " + CR); + throw new Exception("Error scanning symbol " + CR); + } + + try { + scanner.scan(LF); + } catch (Exception e) { + System.out.println("Error scanning symbol " + LF); + throw new Exception("Error scanning symbol " + LF); + } + } + + private void add(ConsoleInputScanner scanner, byte[] sequence) throws Exception { + scanner.scan(ESC); + for (byte b : sequence) { + scanner.scan(b); + } + } + + private void checkInpusStream(ConsoleInputStream in, byte[] expected) throws Exception { + // the actual number of bytes in the stream is two more than the bytes in the array, because of the CR and LF + // symbols, added after the array + byte[] read = new byte[expected.length + 1]; + in.read(read, 0, read.length); + for (int i = 0; i < expected.length; i++) { + Assert.assertEquals("Incorrect char read. Position " + i + ", expected " + expected[i] + ", read " + read[i], expected[i], read[i]); + } + } + +} diff --git a/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/telnet/NegotiationFinishedCallbackTests.java b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/telnet/NegotiationFinishedCallbackTests.java new file mode 100755 index 000000000..225dfdb09 --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/telnet/NegotiationFinishedCallbackTests.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2011 SAP AG + * 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: + * Lazar Kirchev, SAP AG - initial contribution + ******************************************************************************/ + +package org.eclipse.equinox.console.telnet; + +import org.junit.Assert; +import org.junit.Test; + +public class NegotiationFinishedCallbackTests { + + @Test + public void finishTest() throws Exception { + TelnetConnection telnetConnection = null; + telnetConnection = new TelnetConnection (null, null, null); + NegotiationFinishedCallback callback = new NegotiationFinishedCallback(telnetConnection); + callback.finished(); + Assert.assertTrue("Finished not called on console session", telnetConnection.isTelnetNegotiationFinished); + } +} diff --git a/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/telnet/TelnetCommandTests.java b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/telnet/TelnetCommandTests.java new file mode 100755 index 000000000..b32a55b70 --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/telnet/TelnetCommandTests.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2011 SAP AG + * 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: + * Lazar Kirchev, SAP AG - initial API and implementation + *******************************************************************************/ + +package org.eclipse.equinox.console.telnet; + +import java.io.OutputStream; +import java.io.PrintStream; +import java.net.Socket; +import java.util.Dictionary; + +import org.apache.felix.service.command.CommandProcessor; +import org.apache.felix.service.command.CommandSession; +import org.easymock.EasyMock; +import org.eclipse.equinox.console.common.ConsoleInputStream; +import org.junit.Test; +import org.osgi.framework.BundleContext; + + +public class TelnetCommandTests { + + private static final int TEST_CONTENT = 100; + private static final String TELNET_PORT_PROP_NAME = "osgi.console"; + private static final String USE_CONFIG_ADMIN_PROP = "osgi.console.useConfigAdmin"; + private static final String STOP_COMMAND = "stop"; + private static final String HOST = "localhost"; + private static final String FALSE = "false"; + private static final int TELNET_PORT = 2223; + private static final long WAIT_TIME = 5000; + + @Test + public void testTelnetCommand() throws Exception { + CommandSession session = EasyMock.createMock(CommandSession.class); + session.put((String)EasyMock.anyObject(), EasyMock.anyObject()); + EasyMock.expectLastCall().times(3); + EasyMock.expect(session.execute((String)EasyMock.anyObject())).andReturn(new Object()); + session.close(); + EasyMock.expectLastCall(); + EasyMock.replay(session); + + CommandProcessor processor = EasyMock.createMock(CommandProcessor.class); + EasyMock.expect(processor.createSession((ConsoleInputStream)EasyMock.anyObject(), (PrintStream)EasyMock.anyObject(), (PrintStream)EasyMock.anyObject())).andReturn(session); + EasyMock.replay(processor); + + BundleContext context = EasyMock.createMock(BundleContext.class); + EasyMock.expect(context.getProperty(USE_CONFIG_ADMIN_PROP)).andReturn(FALSE); + EasyMock.expect(context.getProperty(TELNET_PORT_PROP_NAME)).andReturn(Integer.toString(TELNET_PORT)); + EasyMock.expect(context.registerService((String)EasyMock.anyObject(), EasyMock.anyObject(), (Dictionary<String, ?>)EasyMock.anyObject())).andReturn(null); + EasyMock.replay(context); + + TelnetCommand command = new TelnetCommand(processor, context); + command.start(); + + Socket socketClient = null; + try { + socketClient = new Socket(HOST, TELNET_PORT); + OutputStream outClient = socketClient.getOutputStream(); + outClient.write(TEST_CONTENT); + outClient.write('\n'); + outClient.flush(); + + // wait for the accept thread to finish execution + try { + Thread.sleep(WAIT_TIME); + } catch (InterruptedException ie) { + // do nothing + } + } finally { + if (socketClient != null) { + socketClient.close(); + } + command.telnet(new String[] {STOP_COMMAND}); + } + EasyMock.verify(context); + } +} diff --git a/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/telnet/TelnetCommandWithConfigAdminTests.java b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/telnet/TelnetCommandWithConfigAdminTests.java new file mode 100755 index 000000000..2eb207297 --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/telnet/TelnetCommandWithConfigAdminTests.java @@ -0,0 +1,196 @@ +package org.eclipse.equinox.console.telnet; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintStream; +import java.net.Socket; +import java.util.Collection; +import java.util.Dictionary; +import java.util.Hashtable; + +import junit.framework.Assert; + +import org.apache.felix.service.command.CommandProcessor; +import org.apache.felix.service.command.CommandSession; +import org.easymock.EasyMock; +import org.easymock.IAnswer; +import org.eclipse.equinox.console.common.ConsoleInputStream; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleException; +import org.osgi.framework.BundleListener; +import org.osgi.framework.Filter; +import org.osgi.framework.FrameworkListener; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceListener; +import org.osgi.framework.ServiceReference; +import org.osgi.framework.ServiceRegistration; +import org.osgi.service.cm.ManagedService; + + +public class TelnetCommandWithConfigAdminTests { + private static final int TEST_CONTENT = 100; + private static final String STOP_COMMAND = "stop"; + private static final String HOST = "localhost"; + private static final String TELNET_PORT = "2223"; + private static final long WAIT_TIME = 5000; + private static final String USE_CONFIG_ADMIN_PROP = "osgi.console.useConfigAdmin"; + private static final String TRUE = "true"; + private static final String FALSE = "false"; + private ManagedService configurator; + + @Test + public void testTelnetCommandWithConfigAdminEnabledTelnet() throws Exception { + CommandSession session = EasyMock.createMock(CommandSession.class); + session.put((String)EasyMock.anyObject(), EasyMock.anyObject()); + EasyMock.expectLastCall().times(3); + EasyMock.expect(session.execute((String)EasyMock.anyObject())).andReturn(new Object()); + session.close(); + EasyMock.expectLastCall(); + EasyMock.replay(session); + + CommandProcessor processor = EasyMock.createMock(CommandProcessor.class); + EasyMock.expect(processor.createSession((ConsoleInputStream)EasyMock.anyObject(), (PrintStream)EasyMock.anyObject(), (PrintStream)EasyMock.anyObject())).andReturn(session); + EasyMock.replay(processor); + + final ServiceRegistration<?> registration = EasyMock.createMock(ServiceRegistration.class); + registration.setProperties((Dictionary)EasyMock.anyObject()); + + EasyMock.expectLastCall(); + EasyMock.replay(registration); + + BundleContext context = EasyMock.createMock(BundleContext.class); + EasyMock.expect(context.getProperty(USE_CONFIG_ADMIN_PROP)).andReturn(TRUE); + EasyMock.expect( + (ServiceRegistration) context.registerService( + (String)EasyMock.anyObject(), + (ManagedService)EasyMock.anyObject(), + (Dictionary<String, ?>)EasyMock.anyObject()) + ).andAnswer((IAnswer<ServiceRegistration<?>>) new IAnswer<ServiceRegistration<?>>() { + public ServiceRegistration<?> answer() { + configurator = (ManagedService) EasyMock.getCurrentArguments()[1]; + return registration; + } + }); + EasyMock.expect( + context.registerService( + (String)EasyMock.anyObject(), + (TelnetCommand)EasyMock.anyObject(), + (Dictionary<String, ?>)EasyMock.anyObject())).andReturn(null); + EasyMock.replay(context); + + TelnetCommand command = new TelnetCommand(processor, context); + command.start(); + Dictionary props = new Hashtable(); + props.put("port", TELNET_PORT); + props.put("host", HOST); + props.put("enabled", TRUE); + configurator.updated(props); + + Socket socketClient = null; + try { + socketClient = new Socket(HOST, Integer.parseInt(TELNET_PORT)); + OutputStream outClient = socketClient.getOutputStream(); + outClient.write(TEST_CONTENT); + outClient.write('\n'); + outClient.flush(); + + // wait for the accept thread to finish execution + try { + Thread.sleep(WAIT_TIME); + } catch (InterruptedException ie) { + // do nothing + } + } finally { + if (socketClient != null) { + socketClient.close(); + } + command.telnet(new String[] {STOP_COMMAND}); + } + EasyMock.verify(context); + } + + @Test + public void testTelnetCommandWithConfigAdminDisabledTelnet() throws Exception { + disabledTelnet(false); + } + + @Test + public void testTelnetCommandWithConfigAdminDisabledTelnetByDefault() throws Exception { + disabledTelnet(true); + } + + private void disabledTelnet(boolean isDefault) throws Exception { + CommandSession session = EasyMock.createMock(CommandSession.class); + session.put((String)EasyMock.anyObject(), EasyMock.anyObject()); + EasyMock.expectLastCall().times(4); + EasyMock.expect(session.execute((String)EasyMock.anyObject())).andReturn(new Object()); + session.close(); + EasyMock.expectLastCall(); + EasyMock.replay(session); + + CommandProcessor processor = EasyMock.createMock(CommandProcessor.class); + EasyMock.expect(processor.createSession((ConsoleInputStream)EasyMock.anyObject(), (PrintStream)EasyMock.anyObject(), (PrintStream)EasyMock.anyObject())).andReturn(session); + EasyMock.replay(processor); + + final ServiceRegistration<?> registration = EasyMock.createMock(ServiceRegistration.class); + registration.setProperties((Dictionary)EasyMock.anyObject()); + + EasyMock.expectLastCall(); + EasyMock.replay(registration); + + BundleContext context = EasyMock.createMock(BundleContext.class); + EasyMock.expect(context.getProperty(USE_CONFIG_ADMIN_PROP)).andReturn(TRUE); + EasyMock.expect( + (ServiceRegistration) context.registerService( + (String)EasyMock.anyObject(), + (ManagedService)EasyMock.anyObject(), + (Dictionary<String, ?>)EasyMock.anyObject()) + ).andAnswer((IAnswer<ServiceRegistration<?>>) new IAnswer<ServiceRegistration<?>>() { + public ServiceRegistration<?> answer() { + configurator = (ManagedService) EasyMock.getCurrentArguments()[1]; + return registration; + } + }); + EasyMock.expect( + context.registerService( + (String)EasyMock.anyObject(), + (TelnetCommand)EasyMock.anyObject(), + (Dictionary<String, ?>)EasyMock.anyObject())).andReturn(null); + EasyMock.replay(context); + + TelnetCommand command = new TelnetCommand(processor, context); + command.start(); + Dictionary props = new Hashtable(); + props.put("port", TELNET_PORT); + props.put("host", HOST); + if (isDefault == false) { + props.put("enabled", FALSE); + } + configurator.updated(props); + + Socket socketClient = null; + try { + socketClient = new Socket(HOST, Integer.parseInt(TELNET_PORT)); + Assert.fail("It should not be possible to open a socket to " + HOST + ":" + TELNET_PORT); + } catch (IOException e) { + // this is ok, there should be an exception + } finally { + if (socketClient != null) { + socketClient.close(); + } + try { + command.telnet(new String[] {STOP_COMMAND}); + } catch (IllegalStateException e) { + //this is expected + } + } + EasyMock.verify(context); + } + +} diff --git a/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/telnet/TelnetConnectionTests.java b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/telnet/TelnetConnectionTests.java new file mode 100755 index 000000000..c133ead89 --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/telnet/TelnetConnectionTests.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright (c) 2011 SAP AG + * 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: + * Lazar Kirchev, SAP AG - initial contribution + ******************************************************************************/ + +package org.eclipse.equinox.console.telnet; + +import org.apache.felix.service.command.CommandProcessor; +import org.apache.felix.service.command.CommandSession; +import org.junit.Assert; +import org.junit.Test; +import org.easymock.EasyMock; +import org.eclipse.equinox.console.common.ConsoleInputStream; + +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintStream; +import java.net.ServerSocket; +import java.net.Socket; + +public class TelnetConnectionTests { + + private static final String HOST = "localhost"; + private static final int TEST_CONTENT = 100; + private static final int IAC = 255; + + @Test + public void testTelneConnection() throws Exception { + ServerSocket servSocket = null; + Socket socketClient = null; + Socket socketServer = null; + TelnetConnection connection = null; + OutputStream outClient = null; + OutputStream outServer = null; + + try { + servSocket = new ServerSocket(0); + socketClient = new Socket(HOST, servSocket.getLocalPort()); + socketServer = servSocket.accept(); + + CommandSession session = EasyMock.createMock(CommandSession.class); + session.put((String)EasyMock.anyObject(), EasyMock.anyObject()); + EasyMock.expectLastCall().times(3); + EasyMock.expect(session.execute((String)EasyMock.anyObject())).andReturn(null); + session.close(); + EasyMock.expectLastCall(); + EasyMock.replay(session); + + CommandProcessor processor = EasyMock.createMock(CommandProcessor.class); + EasyMock.expect(processor.createSession((ConsoleInputStream) EasyMock.anyObject(), (PrintStream) EasyMock.anyObject(), (PrintStream) EasyMock.anyObject())).andReturn(session); + EasyMock.replay(processor); + + connection = new TelnetConnection(socketServer, processor, null); + connection.start(); + + outClient = socketClient.getOutputStream(); + outClient.write(TEST_CONTENT); + outClient.write('\n'); + outClient.flush(); + + InputStream input = socketServer.getInputStream(); + int in = input.read(); + Assert.assertTrue("Server received [" + in + "] instead of " + TEST_CONTENT + " from the telnet client.", in == TEST_CONTENT); + + input = socketClient.getInputStream(); + in = input.read(); + // here IAC is expected, since when the output stream in TelnetConsoleSession is created, several telnet + // commands are written to it, each of them starting with IAC + Assert.assertTrue("Client receive telnet responses from the server unexpected value [" + in + "] instead of " + IAC + ".", in == IAC); + connection.telnetNegotiationFinished(); + Thread.sleep(5000); + EasyMock.verify(session, processor); + } finally { + if (socketClient != null) { + socketClient.close(); + } + if (outClient != null) { + outClient.close(); + } + if (outServer != null) { + outServer.close(); + } + + if (socketServer != null) { + socketServer.close(); + } + + if (servSocket != null) { + servSocket.close(); + } + } + } +} diff --git a/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/telnet/TelnetDisconnectionTest.java b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/telnet/TelnetDisconnectionTest.java new file mode 100755 index 000000000..810d1f524 --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/telnet/TelnetDisconnectionTest.java @@ -0,0 +1,103 @@ +package org.eclipse.equinox.console.telnet; + +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.io.PrintStream; +import java.net.ServerSocket; +import java.net.Socket; + +import org.apache.felix.service.command.CommandProcessor; +import org.apache.felix.service.command.CommandSession; +import org.easymock.EasyMock; +import org.eclipse.equinox.console.commands.DisconnectCommand; +import org.eclipse.equinox.console.common.ConsoleInputStream; +import org.junit.Assert; +import org.junit.Test; +import org.osgi.framework.BundleContext; + +public class TelnetDisconnectionTest { + private static final String HOST = "localhost"; + private InputStream in; + + @Test + public void testTelneConnection() throws Exception { + ServerSocket servSocket = null; + Socket socketClient = null; + Socket socketServer = null; + TelnetConnection connection = null; + OutputStream outClient = null; + OutputStream outServer = null; + + try { + servSocket = new ServerSocket(0); + socketClient = new Socket(HOST, servSocket.getLocalPort()); + socketServer = servSocket.accept(); + + CommandProcessor processor = EasyMock.createMock(CommandProcessor.class); + connection = new TelnetConnection(socketServer, processor, null); + + final CommandSession session = EasyMock.createMock(CommandSession.class); + EasyMock.makeThreadSafe(session, true); + session.put((String)EasyMock.anyObject(), EasyMock.anyObject()); + EasyMock.expectLastCall().times(3); + EasyMock.expect(session.get("CLOSEABLE")).andReturn(connection); + EasyMock.expect(session.execute((String)EasyMock.anyObject())).andReturn(null); + session.close(); + EasyMock.expectLastCall(); + EasyMock.replay(session); + + EasyMock.expect(processor.createSession((ConsoleInputStream) EasyMock.anyObject(), (PrintStream) EasyMock.anyObject(), (PrintStream) EasyMock.anyObject())).andReturn(session); + EasyMock.replay(processor); + + connection.start(); + + BundleContext context = EasyMock.createMock(BundleContext.class); + final DisconnectCommand command = new DisconnectCommand(context); + + PipedOutputStream outputStream = new PipedOutputStream(); + PipedInputStream inputStream = new PipedInputStream(outputStream); + + in = System.in; + System.setIn(inputStream); + + new Thread() { + public void run() { + command.disconnect(session); + } + }.start(); + + outputStream.write(new byte[]{'y'}); + outputStream.write('\n'); + outputStream.flush(); + + Thread.sleep(3000); + Assert.assertTrue("Socket is not closed!", socketServer.isClosed()); + + connection.telnetNegotiationFinished(); + Thread.sleep(5000); + EasyMock.verify(session, processor); + } finally { + if (socketClient != null) { + socketClient.close(); + } + if (outClient != null) { + outClient.close(); + } + if (outServer != null) { + outServer.close(); + } + + if (socketServer != null) { + socketServer.close(); + } + + if (servSocket != null) { + servSocket.close(); + } + + System.setIn(in); + } + } +} diff --git a/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/telnet/TelnetInputHandlerTests.java b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/telnet/TelnetInputHandlerTests.java new file mode 100755 index 000000000..f5d3bd6a8 --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/telnet/TelnetInputHandlerTests.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2011 SAP AG + * 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: + * Lazar Kirchev, SAP AG - initial contribution + ******************************************************************************/ + +package org.eclipse.equinox.console.telnet; + +import org.eclipse.equinox.console.common.ConsoleInputStream; +import org.eclipse.equinox.console.common.ConsoleOutputStream; +import org.junit.Assert; +import org.junit.Test; + +import static org.easymock.EasyMock.*; + +import java.io.ByteArrayOutputStream; +import java.io.StringBufferInputStream; + +public class TelnetInputHandlerTests { + + private static final long WAIT_TIME = 10000; + + @Test + public void testHandler() throws Exception { + StringBufferInputStream input = new StringBufferInputStream("abcde"); + ConsoleInputStream in = new ConsoleInputStream(); + ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); + ConsoleOutputStream out = new ConsoleOutputStream(byteOut); + Callback callback = createMock(Callback.class); + TelnetInputHandler handler = new TelnetInputHandler(input, in, out, callback); + handler.start(); + + // wait for the accept thread to start execution + try { + Thread.sleep(WAIT_TIME); + } catch (InterruptedException ie) { + // do nothing + } + + String res = byteOut.toString(); + Assert.assertTrue("Wrong input. Expected abcde, read " + res, res.equals("abcde")); + } + +} diff --git a/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/telnet/TelnetInputScannerTests.java b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/telnet/TelnetInputScannerTests.java new file mode 100755 index 000000000..1a9290484 --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/telnet/TelnetInputScannerTests.java @@ -0,0 +1,224 @@ +/******************************************************************************* + * Copyright (c) 2011 SAP AG + * 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: + * Lazar Kirchev, SAP AG - initial contribution + ******************************************************************************/ + +package org.eclipse.equinox.console.telnet; + +import org.eclipse.equinox.console.common.ConsoleInputStream; +import org.eclipse.equinox.console.common.ConsoleOutputStream; +import org.eclipse.equinox.console.common.KEYS; +import org.eclipse.equinox.console.common.terminal.ANSITerminalTypeMappings; +import org.eclipse.equinox.console.common.terminal.SCOTerminalTypeMappings; +import org.eclipse.equinox.console.common.terminal.TerminalTypeMappings; +import org.eclipse.equinox.console.common.terminal.VT100TerminalTypeMappings; +import org.eclipse.equinox.console.common.terminal.VT220TerminalTypeMappings; +import org.eclipse.equinox.console.common.terminal.VT320TerminalTypeMappings; +import org.junit.Assert; +import org.junit.Test; + +import static org.easymock.EasyMock.*; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.util.HashMap; +import java.util.Map; + +public class TelnetInputScannerTests { + + private static final int IAC = 255; + + private static final int DO = 253; + + private static final int DO_NOT = 254; + + private static final int TTYPE = 24; + + private static final int WILL = 251; + + private static final int WILL_NOT = 252; + + private static final int SB = 250; + + private static final int SE = 240; + + private static final int EL = 248; + + private static final int SEND = 1; + + private static final int IS = 0; + + protected static final byte ESC = 27; + + @Test + public void testScan() throws Exception { + ConsoleInputStream in = new ConsoleInputStream(); + ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); + ConsoleOutputStream out = new ConsoleOutputStream(byteOut); + Callback callback = createMock(Callback.class); + TelnetInputScanner scanner = new TelnetInputScanner(in, out, callback); + try { + scanner.scan((byte) SE); + scanner.scan((byte) EL); + scanner.scan((byte) SB); + scanner.scan((byte) WILL); + scanner.scan((byte) WILL_NOT); + scanner.scan((byte) DO); + scanner.scan((byte) DO_NOT); + scanner.scan((byte) 'a'); + scanner.scan((byte) 'b'); + scanner.scan((byte) 'c'); + } catch (IOException e) { + System.out.println("Error while scanning: " + e.getMessage()); + e.printStackTrace(); + throw e; + } + + String output = byteOut.toString(); + Assert.assertTrue("Output incorrect. Expected abc, but read " + output, output.equals("abc")); + } + + @Test + public void testScanESC() throws Exception { + ConsoleInputStream in = new ConsoleInputStream(); + ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); + ConsoleOutputStream out = new ConsoleOutputStream(byteOut); + Callback callback = createMock(Callback.class); + TelnetInputScanner scanner = new TelnetInputScanner(in, out, callback); + + try { + scanner.scan((byte) 'a'); + scanner.scan((byte) ESC); + scanner.scan((byte) 'b'); + } catch (IOException e) { + System.out.println("Error while scanning: " + e.getMessage()); + e.printStackTrace(); + throw e; + } + + String output = byteOut.toString(); + Assert.assertTrue("Output incorrect. Expected ab, but read " + output, output.equals("ab")); + } + + @Test + public void testTTNegotiations() throws Exception { + Map<byte[], TerminalTypeMappings> ttMappings = new HashMap<byte[], TerminalTypeMappings>(); + ttMappings.put(new byte[] { 'A', 'N', 'S', 'I' }, new ANSITerminalTypeMappings()); + ttMappings.put(new byte[] { 'V', 'T', '1', '0', '0' }, new VT100TerminalTypeMappings()); + ttMappings.put(new byte[] { 'V', 'T', '2', '2', '0' }, new VT220TerminalTypeMappings()); + ttMappings.put(new byte[] { 'X', 'T', 'E', 'R', 'M' }, new VT220TerminalTypeMappings()); + ttMappings.put(new byte[] { 'V', 'T', '3', '2', '0' }, new VT320TerminalTypeMappings()); + ttMappings.put(new byte[] { 'S', 'C', 'O' }, new SCOTerminalTypeMappings()); + + for (byte[] ttype : ttMappings.keySet()) { + testTerminalTypeNegotiation(ttype, ttMappings.get(ttype)); + } + } + + private void testTerminalTypeNegotiation(byte[] terminalType, TerminalTypeMappings mappings) throws Exception { + PipedInputStream clientIn = new PipedInputStream(); + PipedOutputStream serverOut = new PipedOutputStream(clientIn); + + byte[] requestNegotiation = { (byte) IAC, (byte) DO, (byte) TTYPE }; + + TestCallback testCallback = new TestCallback(); + TelnetOutputStream out = new TelnetOutputStream(serverOut); + TelnetInputScanner scanner = new TelnetInputScanner(new ConsoleInputStream(), out, testCallback); + out.write(requestNegotiation); + out.flush(); + + int read = clientIn.read(); + Assert.assertEquals("Unexpected input ", IAC, read); + read = clientIn.read(); + Assert.assertEquals("Unexpected input ", DO, read); + read = clientIn.read(); + Assert.assertEquals("Unexpected input ", TTYPE, read); + + scanner.scan(IAC); + scanner.scan(WILL); + scanner.scan(TTYPE); + + read = clientIn.read(); + Assert.assertEquals("Unexpected input ", IAC, read); + read = clientIn.read(); + Assert.assertEquals("Unexpected input ", SB, read); + read = clientIn.read(); + Assert.assertEquals("Unexpected input ", TTYPE, read); + read = clientIn.read(); + Assert.assertEquals("Unexpected input ", SEND, read); + read = clientIn.read(); + Assert.assertEquals("Unexpected input ", IAC, read); + read = clientIn.read(); + Assert.assertEquals("Unexpected input ", SE, read); + + scanner.scan(IAC); + scanner.scan(SB); + scanner.scan(TTYPE); + scanner.scan(IS); + scanner.scan('A'); + scanner.scan('B'); + scanner.scan('C'); + scanner.scan('D'); + scanner.scan('E'); + scanner.scan(IAC); + scanner.scan(SE); + + read = clientIn.read(); + Assert.assertEquals("Unexpected input ", IAC, read); + read = clientIn.read(); + Assert.assertEquals("Unexpected input ", SB, read); + read = clientIn.read(); + Assert.assertEquals("Unexpected input ", TTYPE, read); + read = clientIn.read(); + Assert.assertEquals("Unexpected input ", SEND, read); + read = clientIn.read(); + Assert.assertEquals("Unexpected input ", IAC, read); + read = clientIn.read(); + Assert.assertEquals("Unexpected input ", SE, read); + + scanner.scan(IAC); + scanner.scan(SB); + scanner.scan(TTYPE); + scanner.scan(IS); + for (byte symbol : terminalType) { + scanner.scan(symbol); + } + scanner.scan(IAC); + scanner.scan(SE); + + Assert.assertEquals("Incorrect BACKSPACE: ", mappings.getBackspace(), scanner.getBackspace()); + Assert.assertEquals("Incorrect DELL: ", mappings.getDel(), scanner.getDel()); + + Map<String, KEYS> currentEscapesToKey = scanner.getCurrentEscapesToKey(); + Map<String, KEYS> expectedEscapesToKey = mappings.getEscapesToKey(); + for (String escape : expectedEscapesToKey.keySet()) { + KEYS key = expectedEscapesToKey.get(escape); + Assert.assertEquals("Incorrect " + key.name(), key, currentEscapesToKey.get(escape)); + } + + Assert.assertTrue("Callback not called ", testCallback.getState()); + } + + class TestCallback implements Callback { + + private boolean isCalled = false; + + @Override + public void finished() { + isCalled = true; + } + + public boolean getState() { + return isCalled; + } + } + +} diff --git a/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/telnet/TelnetOutputStreamTests.java b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/telnet/TelnetOutputStreamTests.java new file mode 100755 index 000000000..f975f4dc7 --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/telnet/TelnetOutputStreamTests.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2011 SAP AG + * 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: + * Lazar Kirchev, SAP AG - initial contribution + ******************************************************************************/ + +package org.eclipse.equinox.console.telnet; + +import org.junit.Assert; +import org.junit.Test; + +import java.io.ByteArrayOutputStream; + +public class TelnetOutputStreamTests { + + @Test + public void testAutoSend() throws Exception { + ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); + TelnetOutputStream out = new TelnetOutputStream(byteOut); + out.autoSend(); + out.flush(); + byte[] message = byteOut.toByteArray(); + + Assert.assertNotNull("Auto message not sent", message); + Assert.assertFalse("Auto message not sent", message.length == 0); + Assert.assertTrue("Error sending auto message. Expected length: " + TelnetOutputStream.autoMessage.length + ", actual length: " + + message.length, message.length == TelnetOutputStream.autoMessage.length); + + for (int i = 0; i < message.length; i++) { + Assert.assertEquals("Wrong char in auto message. Position: " + i + ", expected: " + TelnetOutputStream.autoMessage[i] + ", read: " + + message[i], TelnetOutputStream.autoMessage[i], message[i]); + } + } +} diff --git a/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/telnet/TelnetServerTests.java b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/telnet/TelnetServerTests.java new file mode 100755 index 000000000..21eb4c546 --- /dev/null +++ b/bundles/org.eclipse.equinox.console.tests/src/org/eclipse/equinox/console/telnet/TelnetServerTests.java @@ -0,0 +1,125 @@ +/******************************************************************************* + * Copyright (c) 2011 SAP AG + * 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: + * Lazar Kirchev, SAP AG - initial contribution + ******************************************************************************/ + +package org.eclipse.equinox.console.telnet; + +import org.apache.felix.service.command.CommandProcessor; +import org.apache.felix.service.command.CommandSession; +import org.easymock.EasyMock; +import org.eclipse.equinox.console.common.ConsoleInputStream; +import org.junit.Assert; +import org.junit.Test; + +import java.io.OutputStream; +import java.io.PrintStream; +import java.net.ConnectException; +import java.net.Socket; +import java.util.ArrayList; +import java.util.List; + +import static org.easymock.EasyMock.*; + +public class TelnetServerTests { + + private static final String HOST = "localhost"; + private static final int PORT = 38888; + private static final long WAIT_TIME = 5000; + private static final int TEST_CONTENT = 100; + + @Test + public void testTelnetServer() throws Exception { + + CommandSession session = EasyMock.createMock(CommandSession.class); + session.put((String)EasyMock.anyObject(), EasyMock.anyObject()); + EasyMock.expectLastCall().times(3); + EasyMock.expect(session.execute((String)EasyMock.anyObject())).andReturn(new Object()); + session.close(); + EasyMock.expectLastCall(); + EasyMock.replay(session); + + CommandProcessor processor = EasyMock.createMock(CommandProcessor.class); + EasyMock.expect(processor.createSession((ConsoleInputStream)EasyMock.anyObject(), (PrintStream)EasyMock.anyObject(), (PrintStream)EasyMock.anyObject())).andReturn(session); + EasyMock.replay(processor); + + List<CommandProcessor> processors = new ArrayList<CommandProcessor>(); + processors.add(processor); + TelnetServer telnetServer = new TelnetServer(null, processors, HOST, PORT); + telnetServer.start(); + Socket socketClient = null; + + try { + socketClient = new Socket("localhost", PORT); + OutputStream outClient = socketClient.getOutputStream(); + outClient.write(TEST_CONTENT); + outClient.write('\n'); + outClient.flush(); + // wait for the accept thread to finish execution + try { + Thread.sleep(WAIT_TIME); + } catch (InterruptedException ie) { + // do nothing + } + verify(); + } catch(ConnectException e) { + Assert.fail("Telnet port not open"); + } finally { + if (socketClient != null) { + socketClient.close(); + } + telnetServer.stopTelnetServer(); + } + } + + @Test + public void testTelnetServerWithoutHost() throws Exception { + CommandSession session = EasyMock.createMock(CommandSession.class); + session.put((String)EasyMock.anyObject(), EasyMock.anyObject()); + EasyMock.expectLastCall().times(4); + EasyMock.expect(session.execute((String)EasyMock.anyObject())).andReturn(new Object()); + session.close(); + EasyMock.expectLastCall(); + EasyMock.replay(session); + + CommandProcessor processor = EasyMock.createMock(CommandProcessor.class); + EasyMock.expect(processor.createSession((ConsoleInputStream)EasyMock.anyObject(), (PrintStream)EasyMock.anyObject(), (PrintStream)EasyMock.anyObject())).andReturn(session); + EasyMock.replay(processor); + + List<CommandProcessor> processors = new ArrayList<CommandProcessor>(); + processors.add(processor); + TelnetServer telnetServer = new TelnetServer(null, processors, null, PORT); + telnetServer.start(); + Socket socketClient = null; + + try { + socketClient = new Socket("localhost", PORT); + OutputStream outClient = socketClient.getOutputStream(); + outClient.write(TEST_CONTENT); + outClient.write('\n'); + outClient.flush(); + + // wait for the accept thread to finish execution + try { + Thread.sleep(WAIT_TIME); + } catch (InterruptedException ie) { + // do nothing + } + } catch(ConnectException e) { + Assert.fail("Telnet port not open"); + } finally { + if (socketClient != null) { + socketClient.close(); + } + telnetServer.stopTelnetServer(); + } + + } + +} |