You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by lg...@apache.org on 2019/02/19 14:46:00 UTC
[mina-sshd] 02/02: [SSHD-897] Moved some shell stream related
classes to sshd-common
This is an automated email from the ASF dual-hosted git repository.
lgoldstein pushed a commit to branch SSHD-897
in repository https://gitbox.apache.org/repos/asf/mina-sshd.git
commit b47195e4f156e475639de2fe3ceae232376b0d1d
Author: Lyor Goldstein <lg...@apache.org>
AuthorDate: Tue Feb 19 16:45:47 2019 +0200
[SSHD-897] Moved some shell stream related classes to sshd-common
---
.../org/apache/sshd/common/channel/PtyMode.java | 108 ++++++++++++++++++++-
.../sshd/server/shell/TtyFilterInputStream.java | 3 +-
.../sshd/server/shell/TtyFilterOutputStream.java | 0
.../apache/sshd/common/channel/PtyModeTest.java | 8 +-
.../sshd/common/channel/PtyModeValueTest.java | 97 ++++++++++++++++++
.../AuthorizedKeyEntryLoginOptionsParseTest.java | 6 +-
.../server/shell/TtyFilterInputStreamTest.java | 4 +-
.../server/shell/TtyFilterOutputStreamTest.java | 8 +-
.../sshd/common/util/io/LineOutputStreamTest.java | 3 +
9 files changed, 222 insertions(+), 15 deletions(-)
diff --git a/sshd-common/src/main/java/org/apache/sshd/common/channel/PtyMode.java b/sshd-common/src/main/java/org/apache/sshd/common/channel/PtyMode.java
index 21af35e..a4745e5 100644
--- a/sshd-common/src/main/java/org/apache/sshd/common/channel/PtyMode.java
+++ b/sshd-common/src/main/java/org/apache/sshd/common/channel/PtyMode.java
@@ -27,6 +27,7 @@ import java.util.Map;
import java.util.NavigableMap;
import java.util.Set;
import java.util.function.Function;
+import java.util.function.ToIntFunction;
import org.apache.sshd.common.util.GenericUtils;
@@ -295,10 +296,29 @@ public enum PtyMode {
public static final Set<PtyMode> MODES =
Collections.unmodifiableSet(EnumSet.allOf(PtyMode.class));
- private static final NavigableMap<Integer, PtyMode> COMMANDS =
+ public static final NavigableMap<Integer, PtyMode> COMMANDS =
Collections.unmodifiableNavigableMap(
GenericUtils.toSortedMap(MODES, PtyMode::toInt, Function.identity(), Comparator.naturalOrder()));
+ /**
+ * A {@code null}-safe {@link ToIntFunction} that returns the {@link PtyMode#toInt()} value and (-1) for {@code null}
+ */
+ public static final ToIntFunction<PtyMode> OPCODE_EXTRACTOR = v -> (v == null) ? -1 : v.toInt();
+
+ /**
+ * A {@code null}-safe {@link Comparator} of {@link PtyMode} values
+ * according to their {@link PtyMode#toInt()} value
+ * @see #OPCODE_EXTRACTOR
+ */
+ public static final Comparator<PtyMode> BY_OPCODE = new Comparator<PtyMode>() {
+ @Override
+ public int compare(PtyMode o1, PtyMode o2) {
+ int v1 = OPCODE_EXTRACTOR.applyAsInt(o1);
+ int v2 = OPCODE_EXTRACTOR.applyAsInt(o2);
+ return Integer.compare(v1, v2);
+ }
+ };
+
private final int v;
PtyMode(int v) {
@@ -318,6 +338,20 @@ public enum PtyMode {
return COMMANDS.get(0x00FF & b);
}
+ public static PtyMode fromName(String name) {
+ if (GenericUtils.isEmpty(name)) {
+ return null;
+ }
+
+ for (PtyMode m : MODES) {
+ if (name.equalsIgnoreCase(m.name())) {
+ return m;
+ }
+ }
+
+ return null;
+ }
+
/**
* @param options The options to enable - ignored if {@code null}/empty
* @return A {@link Map} where all the specified {@link PtyMode}s have {@link #TRUE_SETTING}
@@ -391,6 +425,63 @@ public enum PtyMode {
}
/**
+ * @param modes The {@link Map} of {@link PtyMode}s resolved by the "pty-req" message.
+ * @param enablers A {@link Collection} of enabler settings to be consulted
+ * @param defaultValue The default value to be used if no definite setting could be deduced
+ * @return {@code true} if the CR mode is enabled:</BR>
+ * <UL>
+ * <LI>
+ * If<tt>modes</tt> or <tt>enablers</tt> are {@code null}/empty
+ * then <tt>defaultValue</tt> is used
+ * </LI>
+ *
+ * <LI>
+ * If <U>any</U> of the <tt>enablers</tt> modes are enabled
+ * then the CR mode is enabled.
+ * </LI>
+ *
+ * <LI>
+ * If <U>none</U> of the <tt>enablers</tt> modes were specified
+ * then use <tt>defaultValue</tt>
+ * </LI>
+ *
+ * <LI>
+ * Otherwise (i.e., at least one or more of the <tt>enablers</tt>
+ * modes were specified, but <U>all</U> of them said {@code no})
+ * then {@code false}.
+ * </LI>
+ * </UL>
+ */
+ public static boolean getBooleanSettingValue(
+ Map<PtyMode, ?> modes, Collection<PtyMode> enablers, boolean defaultValue) {
+ if (GenericUtils.isEmpty(modes) || GenericUtils.isEmpty(enablers)) {
+ return defaultValue;
+ }
+
+ int settingsCount = 0;
+ for (PtyMode m : enablers) {
+ Object v = modes.get(m);
+ if (v == null) {
+ continue;
+ }
+
+ settingsCount++;
+
+ // if any setting says yes then use it
+ if (getBooleanSettingValue(v)) {
+ return true;
+ }
+ }
+
+ // ALL (!) settings have said NO
+ if (settingsCount > 0) {
+ return false;
+ } else {
+ return defaultValue; // none of the settings has been found - assume default
+ }
+ }
+
+ /**
* @param v The value to be tested
* @return {@code true} if <U>all</U> of these conditions hold:</BR>
* <UL>
@@ -410,4 +501,19 @@ public enum PtyMode {
public static boolean getBooleanSettingValue(int v) {
return v != 0;
}
+
+ /**
+ * @param m The {@link PtyMode}
+ * @return {@code true} if not {@code null} and one of the settings that
+ * refers to a character value - name usually starts with {@code Vxxx}
+ */
+ public static boolean isCharSetting(PtyMode m) {
+ if (m == null) {
+ return false;
+ }
+
+ String name = m.name();
+ char ch = name.charAt(0);
+ return (ch == 'v') || (ch == 'V');
+ }
}
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/shell/TtyFilterInputStream.java b/sshd-common/src/main/java/org/apache/sshd/server/shell/TtyFilterInputStream.java
similarity index 98%
rename from sshd-core/src/main/java/org/apache/sshd/server/shell/TtyFilterInputStream.java
rename to sshd-common/src/main/java/org/apache/sshd/server/shell/TtyFilterInputStream.java
index b894805..5760310 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/shell/TtyFilterInputStream.java
+++ b/sshd-common/src/main/java/org/apache/sshd/server/shell/TtyFilterInputStream.java
@@ -25,6 +25,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
import org.apache.sshd.common.channel.PtyMode;
@@ -51,7 +52,7 @@ public class TtyFilterInputStream extends FilterInputStream {
}
public TtyFilterInputStream(InputStream in, Collection<PtyMode> ttyOptions) {
- super(in);
+ super(Objects.requireNonNull(in, "No input stream provided"));
// we create a copy of the options so as to avoid concurrent modifications
this.ttyOptions = GenericUtils.of(ttyOptions); // TODO validate non-conflicting options
}
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/shell/TtyFilterOutputStream.java b/sshd-common/src/main/java/org/apache/sshd/server/shell/TtyFilterOutputStream.java
similarity index 100%
rename from sshd-core/src/main/java/org/apache/sshd/server/shell/TtyFilterOutputStream.java
rename to sshd-common/src/main/java/org/apache/sshd/server/shell/TtyFilterOutputStream.java
diff --git a/sshd-common/src/test/java/org/apache/sshd/common/channel/PtyModeTest.java b/sshd-common/src/test/java/org/apache/sshd/common/channel/PtyModeTest.java
index 3234948..69ae5e8 100644
--- a/sshd-common/src/test/java/org/apache/sshd/common/channel/PtyModeTest.java
+++ b/sshd-common/src/test/java/org/apache/sshd/common/channel/PtyModeTest.java
@@ -42,12 +42,8 @@ public class PtyModeTest extends JUnitTestSupport {
}
@Test
- public void testFromInt() {
- for (PtyMode expected : PtyMode.MODES) {
- int num = expected.toInt();
- PtyMode actual = PtyMode.fromInt(num);
- assertSame("Mismatched result for value=" + num, expected, actual);
- }
+ public void testOpcodeExtractorOnNull() {
+ assertEquals(-1, PtyMode.OPCODE_EXTRACTOR.applyAsInt(null));
}
@Test
diff --git a/sshd-common/src/test/java/org/apache/sshd/common/channel/PtyModeValueTest.java b/sshd-common/src/test/java/org/apache/sshd/common/channel/PtyModeValueTest.java
new file mode 100644
index 0000000..98ab7ce
--- /dev/null
+++ b/sshd-common/src/test/java/org/apache/sshd/common/channel/PtyModeValueTest.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sshd.common.channel;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.sshd.util.test.JUnit4ClassRunnerWithParametersFactory;
+import org.apache.sshd.util.test.JUnitTestSupport;
+import org.apache.sshd.util.test.NoIoTestCase;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+import org.junit.runners.Parameterized.UseParametersRunnerFactory;
+
+/**
+ * TODO Add javadoc
+ *
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@RunWith(Parameterized.class) // see https://github.com/junit-team/junit/wiki/Parameterized-tests
+@UseParametersRunnerFactory(JUnit4ClassRunnerWithParametersFactory.class)
+@Category({ NoIoTestCase.class })
+public class PtyModeValueTest extends JUnitTestSupport {
+ private final PtyMode expected;
+
+ public PtyModeValueTest(PtyMode expected) {
+ this.expected = expected;
+ }
+
+ @Parameters(name = "{0}")
+ public static List<Object[]> parameters() {
+ return parameterize(PtyMode.MODES);
+ }
+
+ @Test
+ public void testOpcodeExtractor() {
+ assertEquals(expected.toInt(), PtyMode.OPCODE_EXTRACTOR.applyAsInt(expected));
+ }
+
+ @Test
+ public void testByOpcodeComparator() {
+ int v1 = expected.toInt();
+ for (PtyMode actual : PtyMode.MODES) {
+ int v2 = actual.toInt();
+ int cmpExpected = Integer.signum(Integer.compare(v1, v2));
+ int cmpActual = Integer.signum(PtyMode.BY_OPCODE.compare(expected, actual));
+ assertEquals(expected + " vs. " + actual, cmpExpected, cmpActual);
+ }
+ }
+
+ @Test
+ public void testFromName() {
+ String name = expected.name();
+ for (int index = 0; index < Byte.SIZE; index++) {
+ PtyMode actual = PtyMode.fromName(name);
+ assertSame(name, expected, actual);
+ name = shuffleCase(name);
+ }
+ }
+
+ @Test
+ public void testGetBooleanSettingValueOnNullOrEmptyValues() {
+ for (@SuppressWarnings("unchecked") Map<PtyMode, ?> modes : new Map[] {null, Collections.emptyMap()}) {
+ String s = (modes == null) ? "null" : "empty";
+ assertFalse("Map is " + s, PtyMode.getBooleanSettingValue(modes, expected));
+ }
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + "[" + expected + "]";
+ }
+}
diff --git a/sshd-common/src/test/java/org/apache/sshd/common/config/keys/AuthorizedKeyEntryLoginOptionsParseTest.java b/sshd-common/src/test/java/org/apache/sshd/common/config/keys/AuthorizedKeyEntryLoginOptionsParseTest.java
index d912998..c37aa28 100644
--- a/sshd-common/src/test/java/org/apache/sshd/common/config/keys/AuthorizedKeyEntryLoginOptionsParseTest.java
+++ b/sshd-common/src/test/java/org/apache/sshd/common/config/keys/AuthorizedKeyEntryLoginOptionsParseTest.java
@@ -26,8 +26,10 @@ import java.util.Map;
import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.util.test.JUnit4ClassRunnerWithParametersFactory;
import org.apache.sshd.util.test.JUnitTestSupport;
+import org.apache.sshd.util.test.NoIoTestCase;
import org.junit.FixMethodOrder;
import org.junit.Test;
+import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;
import org.junit.runners.Parameterized;
@@ -40,13 +42,15 @@ import org.junit.runners.Parameterized.UseParametersRunnerFactory;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@RunWith(Parameterized.class) // see https://github.com/junit-team/junit/wiki/Parameterized-tests
@UseParametersRunnerFactory(JUnit4ClassRunnerWithParametersFactory.class)
+@Category({ NoIoTestCase.class })
public class AuthorizedKeyEntryLoginOptionsParseTest extends JUnitTestSupport {
private final String value;
private final String loginPart;
private final String keyPart;
private final Map<String, String> options;
- public AuthorizedKeyEntryLoginOptionsParseTest(String value, String loginPart, String keyPart, Map<String, String> options) {
+ public AuthorizedKeyEntryLoginOptionsParseTest(
+ String value, String loginPart, String keyPart, Map<String, String> options) {
this.value = value;
this.loginPart = loginPart;
this.keyPart = keyPart;
diff --git a/sshd-core/src/test/java/org/apache/sshd/server/shell/TtyFilterInputStreamTest.java b/sshd-common/src/test/java/org/apache/sshd/server/shell/TtyFilterInputStreamTest.java
similarity index 98%
rename from sshd-core/src/test/java/org/apache/sshd/server/shell/TtyFilterInputStreamTest.java
rename to sshd-common/src/test/java/org/apache/sshd/server/shell/TtyFilterInputStreamTest.java
index bd4913a..a17fa01 100644
--- a/sshd-core/src/test/java/org/apache/sshd/server/shell/TtyFilterInputStreamTest.java
+++ b/sshd-common/src/test/java/org/apache/sshd/server/shell/TtyFilterInputStreamTest.java
@@ -40,8 +40,8 @@ import org.apache.sshd.common.channel.PtyMode;
import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
import org.apache.sshd.common.util.io.IoUtils;
-import org.apache.sshd.util.test.BaseTestSupport;
import org.apache.sshd.util.test.JUnit4ClassRunnerWithParametersFactory;
+import org.apache.sshd.util.test.JUnitTestSupport;
import org.apache.sshd.util.test.NoIoTestCase;
import org.junit.FixMethodOrder;
import org.junit.Test;
@@ -59,7 +59,7 @@ import org.junit.runners.Parameterized.UseParametersRunnerFactory;
@RunWith(Parameterized.class) // see https://github.com/junit-team/junit/wiki/Parameterized-tests
@UseParametersRunnerFactory(JUnit4ClassRunnerWithParametersFactory.class)
@Category({ NoIoTestCase.class })
-public class TtyFilterInputStreamTest extends BaseTestSupport {
+public class TtyFilterInputStreamTest extends JUnitTestSupport {
private static final List<PtyMode> MODES =
Collections.unmodifiableList(
Stream.concat(Stream.of(PtyMode.ECHO), TtyFilterInputStream.INPUT_OPTIONS.stream())
diff --git a/sshd-core/src/test/java/org/apache/sshd/server/shell/TtyFilterOutputStreamTest.java b/sshd-common/src/test/java/org/apache/sshd/server/shell/TtyFilterOutputStreamTest.java
similarity index 95%
rename from sshd-core/src/test/java/org/apache/sshd/server/shell/TtyFilterOutputStreamTest.java
rename to sshd-common/src/test/java/org/apache/sshd/server/shell/TtyFilterOutputStreamTest.java
index 5844836..be72b32 100644
--- a/sshd-core/src/test/java/org/apache/sshd/server/shell/TtyFilterOutputStreamTest.java
+++ b/sshd-common/src/test/java/org/apache/sshd/server/shell/TtyFilterOutputStreamTest.java
@@ -34,8 +34,8 @@ import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.sshd.common.channel.PtyMode;
-import org.apache.sshd.util.test.BaseTestSupport;
import org.apache.sshd.util.test.JUnit4ClassRunnerWithParametersFactory;
+import org.apache.sshd.util.test.JUnitTestSupport;
import org.apache.sshd.util.test.NoIoTestCase;
import org.junit.FixMethodOrder;
import org.junit.Test;
@@ -53,7 +53,7 @@ import org.junit.runners.Parameterized.UseParametersRunnerFactory;
@RunWith(Parameterized.class) // see https://github.com/junit-team/junit/wiki/Parameterized-tests
@UseParametersRunnerFactory(JUnit4ClassRunnerWithParametersFactory.class)
@Category({ NoIoTestCase.class })
-public class TtyFilterOutputStreamTest extends BaseTestSupport {
+public class TtyFilterOutputStreamTest extends JUnitTestSupport {
private final PtyMode mode;
public TtyFilterOutputStreamTest(PtyMode mode) {
@@ -71,8 +71,8 @@ public class TtyFilterOutputStreamTest extends BaseTestSupport {
getClass().getSimpleName(), getCurrentTestName(),
"(" + mode + ")", new Date(System.currentTimeMillis()).toString());
- final AtomicInteger crCount = new AtomicInteger(0);
- final AtomicInteger lfCount = new AtomicInteger(0);
+ AtomicInteger crCount = new AtomicInteger(0);
+ AtomicInteger lfCount = new AtomicInteger(0);
try (OutputStream output = new OutputStream() {
@Override
public void write(int b) throws IOException {
diff --git a/sshd-contrib/src/test/java/org/apache/sshd/common/util/io/LineOutputStreamTest.java b/sshd-contrib/src/test/java/org/apache/sshd/common/util/io/LineOutputStreamTest.java
index c49f608..8a449ec 100644
--- a/sshd-contrib/src/test/java/org/apache/sshd/common/util/io/LineOutputStreamTest.java
+++ b/sshd-contrib/src/test/java/org/apache/sshd/common/util/io/LineOutputStreamTest.java
@@ -32,8 +32,10 @@ import java.util.List;
import org.apache.sshd.util.test.JUnit4ClassRunnerWithParametersFactory;
import org.apache.sshd.util.test.JUnitTestSupport;
+import org.apache.sshd.util.test.NoIoTestCase;
import org.junit.FixMethodOrder;
import org.junit.Test;
+import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;
import org.junit.runners.Parameterized;
@@ -46,6 +48,7 @@ import org.junit.runners.Parameterized.UseParametersRunnerFactory;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@RunWith(Parameterized.class) // see https://github.com/junit-team/junit/wiki/Parameterized-tests
@UseParametersRunnerFactory(JUnit4ClassRunnerWithParametersFactory.class)
+@Category({ NoIoTestCase.class })
public class LineOutputStreamTest extends JUnitTestSupport {
private final boolean withCR;