You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by ji...@apache.org on 2018/08/17 15:57:54 UTC

[geode] branch develop updated: GEODE-5531/GEODE-1507: Variable Substitution in GFSH (#2291)

This is an automated email from the ASF dual-hosted git repository.

jinmeiliao pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode.git


The following commit(s) were added to refs/heads/develop by this push:
     new 6355672  GEODE-5531/GEODE-1507: Variable Substitution in GFSH (#2291)
6355672 is described below

commit 635567243a8ba667f04491aa5cfc80e4468822b2
Author: Juan José Ramos <ju...@users.noreply.github.com>
AuthorDate: Fri Aug 17 16:57:49 2018 +0100

    GEODE-5531/GEODE-1507: Variable Substitution in GFSH (#2291)
    
    * `Gfsh.executeCommand` now substitutes all variables (overriding `AbstractShell.executeCommand`) before delegating
    the execution to the parent class (as `Gfsh.executeScriptLine` does).
    * Fixed Performance Tests
---
 .../geode/management/internal/cli/shell/Gfsh.java  |  15 ++-
 .../internal/cli/shell/GfshAbstractUnitTest.java   |  96 +++++++++++++++++
 .../cli/shell/GfshConsoleModeUnitTest.java         |  61 +++++++++++
 .../cli/shell/GfshHeadlessModeUnitTest.java        |  58 +++++++++++
 .../internal/cli/shell/GfshJunitTest.java          | 115 ---------------------
 5 files changed, 229 insertions(+), 116 deletions(-)

diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/Gfsh.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/Gfsh.java
index 8125c8a..cb3a369 100755
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/Gfsh.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/Gfsh.java
@@ -562,6 +562,19 @@ public class Gfsh extends JLineShell {
   }
 
   /**
+   * Executes a single command string.
+   * It substitutes the variables defined within the command, if any, and then delegates to the
+   * default execution.
+   *
+   * @param line command string to be executed
+   * @return command execution result.
+   */
+  @Override
+  public org.springframework.shell.core.CommandResult executeCommand(String line) {
+    return super.executeCommand(!line.contains("$") ? line : expandProperties(line));
+  }
+
+  /**
    * Executes the given command string. We have over-ridden the behavior to extend the original
    * implementation to store the 'last command execution status'.
    *
@@ -1125,7 +1138,7 @@ public class Gfsh extends JLineShell {
     return gfshHistory;
   }
 
-  private String expandProperties(final String input) {
+  protected String expandProperties(final String input) {
     String output = input;
     Scanner s = new Scanner(output);
     String foundInLine;
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/shell/GfshAbstractUnitTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/shell/GfshAbstractUnitTest.java
new file mode 100644
index 0000000..e732df2
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/shell/GfshAbstractUnitTest.java
@@ -0,0 +1,96 @@
+/*
+ * 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.geode.management.internal.cli.shell;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.shell.core.CommandResult;
+
+import org.apache.geode.management.internal.cli.result.LegacyCommandResult;
+
+
+public class GfshAbstractUnitTest {
+  protected Gfsh gfsh;
+  protected String testString;
+
+  @Before
+  public void before() {
+    testString = "This is a test string.";
+  }
+
+  @Test
+  public void testWrapTest() {
+    assertThat(Gfsh.wrapText(testString, 0, -1)).isEqualTo(testString);
+    assertThat(Gfsh.wrapText(testString, 0, 0)).isEqualTo(testString);
+    assertThat(Gfsh.wrapText(testString, 0, 1)).isEqualTo(testString);
+    assertThat(Gfsh.wrapText(testString, 0, 10))
+        .isEqualTo("This is a" + Gfsh.LINE_SEPARATOR + "test" + Gfsh.LINE_SEPARATOR + "string.");
+    assertThat(Gfsh.wrapText(testString, 1, 100)).isEqualTo(Gfsh.LINE_INDENT + testString);
+    assertThat(Gfsh.wrapText(testString, 2, 100))
+        .isEqualTo(Gfsh.LINE_INDENT + Gfsh.LINE_INDENT + testString);
+  }
+
+  @Test
+  public void wrapTextWithNoSpace() {
+    assertThat(Gfsh.wrapText("for datasource", 0, 6))
+        .isEqualTo("for" + Gfsh.LINE_SEPARATOR + "datas" + Gfsh.LINE_SEPARATOR + "ource");
+    assertThat(Gfsh.wrapText("for data sour ", 0, 6))
+        .isEqualTo("for" + Gfsh.LINE_SEPARATOR + "data" + Gfsh.LINE_SEPARATOR + "sour ");
+    assertThat(Gfsh.wrapText("for data sour ", 0, 5)).isEqualTo(
+        "for" + Gfsh.LINE_SEPARATOR + "data" + Gfsh.LINE_SEPARATOR + "sour" + Gfsh.LINE_SEPARATOR);
+  }
+
+  @Test
+  public void getAppContextPath() {
+    gfsh = new Gfsh();
+    assertThat(gfsh.getEnvAppContextPath()).isEqualTo("");
+    gfsh.setEnvProperty(Gfsh.ENV_APP_CONTEXT_PATH, "test");
+    assertThat(gfsh.getEnvAppContextPath()).isEqualTo("test");
+  }
+
+  @Test
+  public void executeCommandShouldSubstituteVariablesWhenNeededAndDelegateToDefaultImplementation() {
+    gfsh = spy(Gfsh.class);
+    CommandResult commandResult;
+
+    // No '$' character, should only delegate to default implementation.
+    commandResult = gfsh.executeCommand("echo --string=ApacheGeode!");
+    assertThat(commandResult.isSuccess()).isTrue();
+    verify(gfsh, times(0)).expandProperties("echo --string=ApacheGeode!");
+    assertThat(((LegacyCommandResult) commandResult.getResult()).getMessageFromContent())
+        .isEqualTo("ApacheGeode!");
+
+    // '$' character present, should expand properties and delegate to default implementation.
+    commandResult = gfsh.executeCommand("echo --string=SYS_USER:${SYS_USER}");
+    assertThat(commandResult.isSuccess()).isTrue();
+    verify(gfsh, times(1)).expandProperties("echo --string=SYS_USER:${SYS_USER}");
+    assertThat(((LegacyCommandResult) commandResult.getResult()).getMessageFromContent())
+        .isEqualTo("SYS_USER:" + System.getProperty("user.name"));
+
+    // '$' character present but not variable referenced, should try to expand, find nothing (no
+    // replacement) and delegate to default implementation.
+    commandResult = gfsh.executeCommand("echo --string=MyNameIs:$USER_NAME");
+    assertThat(commandResult.isSuccess()).isTrue();
+    verify(gfsh, times(1)).expandProperties("echo --string=MyNameIs:$USER_NAME");
+    assertThat(((LegacyCommandResult) commandResult.getResult()).getMessageFromContent())
+        .isEqualTo("MyNameIs:$USER_NAME");
+  }
+}
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/shell/GfshConsoleModeUnitTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/shell/GfshConsoleModeUnitTest.java
new file mode 100644
index 0000000..d63b578
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/shell/GfshConsoleModeUnitTest.java
@@ -0,0 +1,61 @@
+/*
+ * 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.geode.management.internal.cli.shell;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.Enumeration;
+import java.util.logging.LogManager;
+import java.util.logging.Logger;
+
+import org.junit.Before;
+import org.junit.Test;
+
+
+public class GfshConsoleModeUnitTest extends GfshAbstractUnitTest {
+
+  @Before
+  public void before() {
+    super.before();
+    gfsh = new Gfsh(true, null, new GfshConfig());
+  }
+
+  @Test
+  public void consoleModeShouldRedirectOnlyJDKLoggers() {
+    gfsh = new Gfsh(true, null, new GfshConfig());
+    LogManager logManager = LogManager.getLogManager();
+    Enumeration<String> loggerNames = logManager.getLoggerNames();
+    // when initialized in console mode, all log messages will show up in console
+    // initially. so that we see messages when "start locator", "start server" command
+    // are executed. Only after connection, JDK's logging is turned off
+    while (loggerNames.hasMoreElements()) {
+      String loggerName = loggerNames.nextElement();
+      Logger logger = logManager.getLogger(loggerName);
+      // make sure jdk's logging goes to the gfsh log file
+      if (loggerName.startsWith("java")) {
+        assertThat(logger.getParent().getName()).endsWith("LogWrapper");
+      }
+      // make sure Gfsh's logging goes to the gfsh log file
+      else if (loggerName.endsWith(".Gfsh")) {
+        assertThat(logger.getParent().getName()).doesNotEndWith("LogWrapper");
+      }
+      // make sure SimpleParser's logging will still show up in the console
+      else if (loggerName.endsWith(".SimpleParser")) {
+        assertThat(logger.getParent().getName()).doesNotEndWith("LogWrapper");
+      }
+    }
+  }
+}
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/shell/GfshHeadlessModeUnitTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/shell/GfshHeadlessModeUnitTest.java
new file mode 100644
index 0000000..e7c65a4
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/shell/GfshHeadlessModeUnitTest.java
@@ -0,0 +1,58 @@
+/*
+ * 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.geode.management.internal.cli.shell;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.Enumeration;
+import java.util.logging.LogManager;
+import java.util.logging.Logger;
+
+import org.junit.Before;
+import org.junit.Test;
+
+
+public class GfshHeadlessModeUnitTest extends GfshAbstractUnitTest {
+
+  @Before
+  public void before() {
+    super.before();
+    gfsh = new Gfsh(false, null, new GfshConfig());
+  }
+
+  @Test
+  public void headlessModeShouldRedirectBothJDKAndGFSHLoggers() {
+    gfsh = new Gfsh(false, null, new GfshConfig());
+    LogManager logManager = LogManager.getLogManager();
+    Enumeration<String> loggerNames = logManager.getLoggerNames();
+    while (loggerNames.hasMoreElements()) {
+      String loggerName = loggerNames.nextElement();
+      Logger logger = logManager.getLogger(loggerName);
+      // make sure jdk's logging goes to the gfsh log file
+      if (loggerName.startsWith("java")) {
+        assertThat(logger.getParent().getName()).endsWith("LogWrapper");
+      }
+      // make sure Gfsh's logging goes to the gfsh log file
+      else if (loggerName.endsWith(".Gfsh")) {
+        assertThat(logger.getParent().getName()).endsWith("LogWrapper");
+      }
+      // make sure SimpleParser's logging will still show up in the console
+      else if (loggerName.endsWith(".SimpleParser")) {
+        assertThat(logger.getParent().getName()).doesNotEndWith("LogWrapper");
+      }
+    }
+  }
+}
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/shell/GfshJunitTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/shell/GfshJunitTest.java
deleted file mode 100644
index 31a4847..0000000
--- a/geode-core/src/test/java/org/apache/geode/management/internal/cli/shell/GfshJunitTest.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * 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.geode.management.internal.cli.shell;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.util.Enumeration;
-import java.util.logging.LogManager;
-import java.util.logging.Logger;
-
-import org.junit.Before;
-import org.junit.Test;
-
-
-public class GfshJunitTest {
-  private String testString;
-  private Gfsh gfsh;
-
-  @Before
-  public void before() {
-    testString = "This is a test string.";
-  }
-
-  @Test
-  public void testWrapTest() {
-    assertThat(Gfsh.wrapText(testString, 0, -1)).isEqualTo(testString);
-    assertThat(Gfsh.wrapText(testString, 0, 0)).isEqualTo(testString);
-    assertThat(Gfsh.wrapText(testString, 0, 1)).isEqualTo(testString);
-    assertThat(Gfsh.wrapText(testString, 0, 10))
-        .isEqualTo("This is a" + Gfsh.LINE_SEPARATOR + "test" + Gfsh.LINE_SEPARATOR + "string.");
-    assertThat(Gfsh.wrapText(testString, 1, 100)).isEqualTo(Gfsh.LINE_INDENT + testString);
-    assertThat(Gfsh.wrapText(testString, 2, 100))
-        .isEqualTo(Gfsh.LINE_INDENT + Gfsh.LINE_INDENT + testString);
-  }
-
-  @Test
-  public void wrapTextWithNoSpace() {
-    assertThat(Gfsh.wrapText("for datasource", 0, 6))
-        .isEqualTo("for" + Gfsh.LINE_SEPARATOR + "datas" + Gfsh.LINE_SEPARATOR + "ource");
-    assertThat(Gfsh.wrapText("for data sour ", 0, 6))
-        .isEqualTo("for" + Gfsh.LINE_SEPARATOR + "data" + Gfsh.LINE_SEPARATOR + "sour ");
-    assertThat(Gfsh.wrapText("for data sour ", 0, 5)).isEqualTo(
-        "for" + Gfsh.LINE_SEPARATOR + "data" + Gfsh.LINE_SEPARATOR + "sour" + Gfsh.LINE_SEPARATOR);
-  }
-
-  @Test
-  public void getAppContextPath() throws Exception {
-    gfsh = new Gfsh();
-    assertThat(gfsh.getEnvAppContextPath()).isEqualTo("");
-    gfsh.setEnvProperty(Gfsh.ENV_APP_CONTEXT_PATH, "test");
-    assertThat(gfsh.getEnvAppContextPath()).isEqualTo("test");
-  }
-
-  @Test
-  public void loggerParentInHeadlessMode() {
-    gfsh = new Gfsh(false, null, new GfshConfig());
-    LogManager logManager = LogManager.getLogManager();
-    Enumeration<String> loggerNames = logManager.getLoggerNames();
-    while (loggerNames.hasMoreElements()) {
-      String loggerName = loggerNames.nextElement();
-      Logger logger = logManager.getLogger(loggerName);
-      // make sure jdk's logging goes to the gfsh log file
-      if (loggerName.startsWith("java")) {
-        assertThat(logger.getParent().getName()).endsWith("LogWrapper");
-      }
-      // make sure Gfsh's logging goes to the gfsh log file
-      else if (loggerName.endsWith(".Gfsh")) {
-        assertThat(logger.getParent().getName()).endsWith("LogWrapper");
-      }
-      // make sure SimpleParser's logging will still show up in the console
-      else if (loggerName.endsWith(".SimpleParser")) {
-        assertThat(logger.getParent().getName()).doesNotEndWith("LogWrapper");
-      }
-    }
-  }
-
-  @Test
-  public void loggerParentInConsoleMode() {
-    gfsh = new Gfsh(true, null, new GfshConfig());
-    LogManager logManager = LogManager.getLogManager();
-    Enumeration<String> loggerNames = logManager.getLoggerNames();
-    // when initialized in console mode, all log messages will show up in console
-    // initially. so that we see messages when "start locator", "start server" command
-    // are executed. Only after connection, JDK's logging is turned off
-    while (loggerNames.hasMoreElements()) {
-      String loggerName = loggerNames.nextElement();
-      Logger logger = logManager.getLogger(loggerName);
-      // make sure jdk's logging goes to the gfsh log file
-      if (loggerName.startsWith("java")) {
-        assertThat(logger.getParent().getName()).endsWith("LogWrapper");
-      }
-      // make sure Gfsh's logging goes to the gfsh log file
-      else if (loggerName.endsWith(".Gfsh")) {
-        assertThat(logger.getParent().getName()).doesNotEndWith("LogWrapper");
-      }
-      // make sure SimpleParser's logging will still show up in the console
-      else if (loggerName.endsWith(".SimpleParser")) {
-        assertThat(logger.getParent().getName()).doesNotEndWith("LogWrapper");
-      }
-    }
-  }
-}