geode-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jinmeil...@apache.org
Subject [5/7] geode git commit: GEODE-2267: add validation to the arguments and include export stats in the command
Date Sat, 04 Mar 2017 00:04:15 GMT
http://git-wip-us.apache.org/repos/asf/geode/blob/bf788176/geode-core/src/test/java/org/apache/geode/management/internal/cli/util/LogLevelExtractorTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/util/LogLevelExtractorTest.java
b/geode-core/src/test/java/org/apache/geode/management/internal/cli/util/LogLevelExtractorTest.java
index 320a3bc..fd7d68b 100644
--- a/geode-core/src/test/java/org/apache/geode/management/internal/cli/util/LogLevelExtractorTest.java
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/util/LogLevelExtractorTest.java
@@ -20,11 +20,10 @@ package org.apache.geode.management.internal.cli.util;
 import static org.assertj.core.api.Assertions.assertThat;
 
 import org.apache.geode.test.junit.categories.UnitTest;
+import org.apache.logging.log4j.Level;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
-import java.time.LocalDateTime;
-
 @Category(UnitTest.class)
 public class LogLevelExtractorTest {
   @Test
@@ -35,12 +34,49 @@ public class LogLevelExtractorTest {
     LogLevelExtractor.Result result = LogLevelExtractor.extract(logLine);
 
     assertThat(result).isNotNull();
-    assertThat(result.getLogLevel()).isEqualTo("info");
+    assertThat(result.getLogLevel()).isEqualTo(Level.INFO);
 
     assertThat(result.getLogTimestamp().toString()).isEqualTo("2017-02-07T11:16:36.694");
   }
 
   @Test
+  public void extractWorksForFine() throws Exception {
+    String logLine =
+        "[fine 2017/02/07 11:16:36.694 PST locator1 <locator request thread[1]> tid=0x27]
Mapped \"{[/v1/async-event-queues],methods=[GET]}\" onto public java.lang.String";
+
+    LogLevelExtractor.Result result = LogLevelExtractor.extract(logLine);
+
+    assertThat(result).isNotNull();
+    assertThat(result.getLogLevel()).isEqualTo(Level.DEBUG);
+
+    assertThat(result.getLogTimestamp().toString()).isEqualTo("2017-02-07T11:16:36.694");
+  }
+
+  @Test
+  public void extractWorksForFiner() throws Exception {
+    String logLine =
+        "[finer 2017/02/07 11:16:36.694 PST locator1 <locator request thread[1]> tid=0x27]
Mapped \"{[/v1/async-event-queues],methods=[GET]}\" onto public java.lang.String";
+
+    LogLevelExtractor.Result result = LogLevelExtractor.extract(logLine);
+
+    assertThat(result).isNotNull();
+    assertThat(result.getLogLevel()).isEqualTo(Level.TRACE);
+    assertThat(result.getLogTimestamp().toString()).isEqualTo("2017-02-07T11:16:36.694");
+  }
+
+  @Test
+  public void extractWorksForFinest() throws Exception {
+    String logLine =
+        "[finest 2017/02/07 11:16:36.694 PST locator1 <locator request thread[1]> tid=0x27]
Mapped \"{[/v1/async-event-queues],methods=[GET]}\" onto public java.lang.String";
+
+    LogLevelExtractor.Result result = LogLevelExtractor.extract(logLine);
+
+    assertThat(result).isNotNull();
+    assertThat(result.getLogLevel()).isEqualTo(Level.TRACE);
+    assertThat(result.getLogTimestamp().toString()).isEqualTo("2017-02-07T11:16:36.694");
+  }
+
+  @Test
   public void extractReturnsNullIfNoTimestamp() throws Exception {
     String logLine = "[info (this line is not a valid log statement since it has no timestamp)";
 
@@ -58,4 +94,24 @@ public class LogLevelExtractorTest {
     assertThat(result).isNull();
   }
 
+  @Test
+  public void testGetLevel() {
+    assertThat(LogLevelExtractor.getLevel("all")).isEqualTo(Level.ALL);
+    assertThat(LogLevelExtractor.getLevel("fatal")).isEqualTo(Level.FATAL);
+    assertThat(LogLevelExtractor.getLevel("severe")).isEqualTo(Level.FATAL);
+    assertThat(LogLevelExtractor.getLevel("error")).isEqualTo(Level.ERROR);
+    assertThat(LogLevelExtractor.getLevel("warn")).isEqualTo(Level.WARN);
+    assertThat(LogLevelExtractor.getLevel("warning")).isEqualTo(Level.WARN);
+    assertThat(LogLevelExtractor.getLevel("info")).isEqualTo(Level.INFO);
+    assertThat(LogLevelExtractor.getLevel("config")).isEqualTo(Level.DEBUG);
+    assertThat(LogLevelExtractor.getLevel("debug")).isEqualTo(Level.DEBUG);
+    assertThat(LogLevelExtractor.getLevel("fine")).isEqualTo(Level.DEBUG);
+    assertThat(LogLevelExtractor.getLevel("finer")).isEqualTo(Level.TRACE);
+    assertThat(LogLevelExtractor.getLevel("finest")).isEqualTo(Level.TRACE);
+    assertThat(LogLevelExtractor.getLevel("all")).isEqualTo(Level.ALL);
+    assertThat(LogLevelExtractor.getLevel("none")).isEqualTo(Level.OFF);
+    assertThat(LogLevelExtractor.getLevel("notrecognizable")).isEqualTo(Level.OFF);
+
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/geode/blob/bf788176/geode-core/src/test/java/org/apache/geode/management/internal/security/MultiUserDUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/security/MultiUserDUnitTest.java
b/geode-core/src/test/java/org/apache/geode/management/internal/security/MultiUserDUnitTest.java
index 37e7f45..255048d 100644
--- a/geode-core/src/test/java/org/apache/geode/management/internal/security/MultiUserDUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/security/MultiUserDUnitTest.java
@@ -14,19 +14,11 @@
  */
 package org.apache.geode.management.internal.security;
 
-import static org.apache.geode.distributed.ConfigurationProperties.*;
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.Properties;
-import java.util.concurrent.TimeUnit;
-
-import org.awaitility.Awaitility;
-import org.apache.geode.security.TestSecurityManager;
-import org.json.JSONException;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import static org.apache.geode.distributed.ConfigurationProperties.NAME;
+import static org.apache.geode.distributed.ConfigurationProperties.SECURITY_MANAGER;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
 
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.management.cli.Result.Status;
@@ -35,6 +27,7 @@ import org.apache.geode.management.internal.cli.commands.CliCommandTestBase;
 import org.apache.geode.management.internal.cli.result.CommandResult;
 import org.apache.geode.management.internal.cli.result.ErrorResultData;
 import org.apache.geode.management.internal.cli.result.ResultBuilder;
+import org.apache.geode.security.TestSecurityManager;
 import org.apache.geode.test.dunit.AsyncInvocation;
 import org.apache.geode.test.dunit.Host;
 import org.apache.geode.test.dunit.IgnoredException;
@@ -42,6 +35,15 @@ import org.apache.geode.test.dunit.VM;
 import org.apache.geode.test.junit.categories.DistributedTest;
 import org.apache.geode.test.junit.categories.FlakyTest;
 import org.apache.geode.test.junit.categories.SecurityTest;
+import org.awaitility.Awaitility;
+import org.json.JSONException;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Properties;
+import java.util.concurrent.TimeUnit;
 
 @Category({DistributedTest.class, SecurityTest.class})
 public class MultiUserDUnitTest extends CliCommandTestBase {
@@ -49,6 +51,8 @@ public class MultiUserDUnitTest extends CliCommandTestBase {
   @Category(FlakyTest.class) // GEODE-1579
   @Test
   public void testMultiUser() throws IOException, JSONException, InterruptedException {
+    IgnoredException.addIgnoredException("java.util.zip.ZipException: zip file is empty");
+
     Properties properties = new Properties();
     properties.put(NAME, MultiUserDUnitTest.class.getSimpleName());
     properties.put(SECURITY_MANAGER, TestSecurityManager.class.getName());

http://git-wip-us.apache.org/repos/asf/geode/blob/bf788176/geode-core/src/test/java/org/apache/geode/test/dunit/rules/GfshShellConnectionRule.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/GfshShellConnectionRule.java
b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/GfshShellConnectionRule.java
index dd0939e..f35e3e9 100644
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/GfshShellConnectionRule.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/GfshShellConnectionRule.java
@@ -169,12 +169,16 @@ public class GfshShellConnectionRule extends DescribedExternalResource
{
   public CommandResult executeCommand(String command) throws Exception {
     gfsh.executeCommand(command);
     CommandResult result = (CommandResult) gfsh.getResult();
-    if (StringUtils.isBlank(gfsh.outputString)) {
-      // print out the message body as the command result
-      JSONArray messages = ((JSONArray) result.getContent().get("message"));
-      if (messages != null) {
-        for (int i = 0; i < messages.length(); i++) {
-          gfsh.outputString += messages.getString(i) + "\n";
+    if (StringUtils.isBlank(gfsh.outputString) && result != null && result.getContent()
!= null) {
+      if (result.getStatus() == Result.Status.ERROR) {
+        gfsh.outputString = result.toString();
+      } else {
+        // print out the message body as the command result
+        JSONArray messages = ((JSONArray) result.getContent().get("message"));
+        if (messages != null) {
+          for (int i = 0; i < messages.length(); i++) {
+            gfsh.outputString += messages.getString(i) + "\n";
+          }
         }
       }
     }

http://git-wip-us.apache.org/repos/asf/geode/blob/bf788176/geode-core/src/test/java/org/apache/geode/test/dunit/rules/LocatorServerStartupRule.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/LocatorServerStartupRule.java
b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/LocatorServerStartupRule.java
index ad8c033..d5a4dfb 100644
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/LocatorServerStartupRule.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/LocatorServerStartupRule.java
@@ -107,8 +107,7 @@ public class LocatorServerStartupRule extends ExternalResource implements
Serial
   }
 
   /**
-   * starts a cache server that does not connect to a locator, unless the properties it passes
in
-   * has "locators" property.
+   * starts a cache server that does not connect to a locator
    * 
    * @return VM node vm
    */
@@ -118,11 +117,6 @@ public class LocatorServerStartupRule extends ExternalResource implements
Serial
 
   /**
    * start a server that connects to this locatorPort
-   *
-   * @param index
-   * @param locatorPort
-   * @return
-   * @throws IOException
    */
   public Server startServerVM(int index, int locatorPort) throws IOException {
     return startServerVM(index, new Properties(), locatorPort);
@@ -149,6 +143,7 @@ public class LocatorServerStartupRule extends ExternalResource implements
Serial
    */
   public Server startServerVM(int index, Properties properties, int locatorPort)
       throws IOException {
+
     String name = "server-" + index;
     properties.setProperty(NAME, name);
 

http://git-wip-us.apache.org/repos/asf/geode/blob/bf788176/geode-core/src/test/resources/org/apache/geode/codeAnalysis/sanctionedSerializables.txt
----------------------------------------------------------------------
diff --git a/geode-core/src/test/resources/org/apache/geode/codeAnalysis/sanctionedSerializables.txt
b/geode-core/src/test/resources/org/apache/geode/codeAnalysis/sanctionedSerializables.txt
index b1d6887..a11c7ad 100755
--- a/geode-core/src/test/resources/org/apache/geode/codeAnalysis/sanctionedSerializables.txt
+++ b/geode-core/src/test/resources/org/apache/geode/codeAnalysis/sanctionedSerializables.txt
@@ -564,7 +564,7 @@ org/apache/geode/management/internal/cli/functions/DestroyIndexFunction,true,1
 org/apache/geode/management/internal/cli/functions/ExportConfigFunction,true,1
 org/apache/geode/management/internal/cli/functions/ExportDataFunction,true,1
 org/apache/geode/management/internal/cli/functions/ExportLogsFunction,true,1
-org/apache/geode/management/internal/cli/functions/ExportLogsFunction$Args,false,endTime:java/lang/String,logLevel:java/lang/String,logLevelOnly:boolean,startTime:java/lang/String
+org/apache/geode/management/internal/cli/functions/ExportLogsFunction$Args,false,endTime:java/time/LocalDateTime,includeLogs:boolean,includeStats:boolean,logLevel:org/apache/logging/log4j/Level,startTime:java/time/LocalDateTime,thisLogLevelOnly:boolean
 org/apache/geode/management/internal/cli/functions/FetchRegionAttributesFunction,true,4366812590788342070
 org/apache/geode/management/internal/cli/functions/FetchRegionAttributesFunction$FetchRegionAttributesFunctionResult,true,-3970828263897978845,cacheListenerClasses:java/lang/String[],cacheLoaderClass:java/lang/String,cacheWriterClass:java/lang/String,regionAttributes:org/apache/geode/cache/RegionAttributes
 org/apache/geode/management/internal/cli/functions/FetchSharedConfigurationStatusFunction,true,1
@@ -620,7 +620,7 @@ org/apache/geode/management/internal/cli/shell/JMXInvocationException,true,-4265
 org/apache/geode/management/internal/cli/shell/jline/ANSIHandler$ANSIStyle,false
 org/apache/geode/management/internal/cli/util/DiskStoreNotFoundException,true,-5184836041554948093
 org/apache/geode/management/internal/cli/util/EvictionAttributesInfo,true,1,evictionAction:java/lang/String,evictionAlgorithm:java/lang/String,evictionMaxValue:int
-org/apache/geode/management/internal/cli/util/ExportLogsCacheWriter,false,currentFile:java/nio/file/Path,currentOutputStream:java/io/BufferedOutputStream
+org/apache/geode/management/internal/cli/util/ExportLogsCacheWriter,false,currentFile:java/nio/file/Path,currentOutputStream:java/io/BufferedOutputStream,isEmpty:boolean
 org/apache/geode/management/internal/cli/util/FixedPartitionAttributesInfo,false,isPrimary:boolean,numBuckets:int,partitionName:java/lang/String
 org/apache/geode/management/internal/cli/util/JConsoleNotFoundException,true,-1485615321440327206
 org/apache/geode/management/internal/cli/util/LogFilter$LineFilterResult,false

http://git-wip-us.apache.org/repos/asf/geode/blob/bf788176/geode-core/src/test/resources/org/apache/geode/management/internal/cli/commands/golden-help-offline.properties
----------------------------------------------------------------------
diff --git a/geode-core/src/test/resources/org/apache/geode/management/internal/cli/commands/golden-help-offline.properties
b/geode-core/src/test/resources/org/apache/geode/management/internal/cli/commands/golden-help-offline.properties
index 2c27654..8e21a3a 100644
--- a/geode-core/src/test/resources/org/apache/geode/management/internal/cli/commands/golden-help-offline.properties
+++ b/geode-core/src/test/resources/org/apache/geode/management/internal/cli/commands/golden-help-offline.properties
@@ -1470,7 +1470,7 @@ SYNOPSIS\n\
 SYNTAX\n\
 \ \ \ \ export logs [--dir=value] [--group=value(nullvalue)*] [--member=value(nullvalue)*]\n\
 \ \ \ \ [--log-level=value] [--only-log-level=value] [--merge-log=value] [--start-time=value]\n\
-\ \ \ \ [--end-time=value]\n\
+\ \ \ \ [--end-time=value] [--logs-only(=value)?] [--stats-only(=value)?]\n\
 PARAMETERS\n\
 \ \ \ \ dir\n\
 \ \ \ \ \ \ \ \ Local directory to which log files will be written. This is only used when
you are\n\
@@ -1483,9 +1483,10 @@ PARAMETERS\n\
 \ \ \ \ \ \ \ \ Name/Id of the member whose log files will be exported.\n\
 \ \ \ \ \ \ \ \ Required: false\n\
 \ \ \ \ log-level\n\
-\ \ \ \ \ \ \ \ Minimum level of log entries to export. Valid values are: none, error, info,
config , fine,\n\
-\ \ \ \ \ \ \ \ finer and finest.  The default is "info".\n\
+\ \ \ \ \ \ \ \ Minimum level of log entries to export. Valid values are: fatal, error, warn,
info, debug,\n\
+\ \ \ \ \ \ \ \ trace and all.  The default is "INFO".\n\
 \ \ \ \ \ \ \ \ Required: false\n\
+\ \ \ \ \ \ \ \ Default (if the parameter is not specified): INFO\n\
 \ \ \ \ only-log-level\n\
 \ \ \ \ \ \ \ \ Whether to only include those entries that exactly match the --log-level
specified.\n\
 \ \ \ \ \ \ \ \ Required: false\n\
@@ -1502,6 +1503,16 @@ PARAMETERS\n\
 \ \ \ \ \ \ \ \ Log entries that occurred before this time will be exported. The default
is no limit.\n\
 \ \ \ \ \ \ \ \ Format: yyyy/MM/dd/HH/mm/ss/SSS/z OR yyyy/MM/dd\n\
 \ \ \ \ \ \ \ \ Required: false\n\
+\ \ \ \ logs-only\n\
+\ \ \ \ \ \ \ \ Whether to only export logs\n\
+\ \ \ \ \ \ \ \ Required: false\n\
+\ \ \ \ \ \ \ \ Default (if the parameter is specified without value): true\n\
+\ \ \ \ \ \ \ \ Default (if the parameter is not specified): false\n\
+\ \ \ \ stats-only\n\
+\ \ \ \ \ \ \ \ Whether to only export statistics\n\
+\ \ \ \ \ \ \ \ Required: false\n\
+\ \ \ \ \ \ \ \ Default (if the parameter is specified without value): true\n\
+\ \ \ \ \ \ \ \ Default (if the parameter is not specified): false\n\
 
 export-offline-disk-store.help=\
 NAME\n\

http://git-wip-us.apache.org/repos/asf/geode/blob/bf788176/geode-web/src/test/java/org/apache/geode/management/internal/cli/commands/ExportLogsOverHttpDUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-web/src/test/java/org/apache/geode/management/internal/cli/commands/ExportLogsOverHttpDUnitTest.java
b/geode-web/src/test/java/org/apache/geode/management/internal/cli/commands/ExportLogsOverHttpDUnitTest.java
index 8f8342f..8c9442a 100644
--- a/geode-web/src/test/java/org/apache/geode/management/internal/cli/commands/ExportLogsOverHttpDUnitTest.java
+++ b/geode-web/src/test/java/org/apache/geode/management/internal/cli/commands/ExportLogsOverHttpDUnitTest.java
@@ -15,102 +15,52 @@
 
 package org.apache.geode.management.internal.cli.commands;
 
-import static org.apache.geode.distributed.ConfigurationProperties.HTTP_SERVICE_BIND_ADDRESS;
-import static org.apache.geode.distributed.ConfigurationProperties.HTTP_SERVICE_PORT;
-import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_PORT;
 import static org.assertj.core.api.Assertions.assertThat;
 
-import com.google.common.collect.Sets;
-
-import org.apache.geode.internal.AvailablePortHelper;
 import org.apache.geode.test.dunit.rules.GfshShellConnectionRule;
-import org.apache.geode.test.dunit.rules.Locator;
-import org.apache.geode.test.dunit.rules.LocatorServerStartupRule;
 import org.apache.geode.test.junit.categories.DistributedTest;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 import org.junit.rules.TemporaryFolder;
 
 import java.io.File;
-import java.util.HashSet;
-import java.util.Properties;
 import java.util.Set;
 import java.util.stream.Collectors;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 
 @Category(DistributedTest.class)
-public class ExportLogsOverHttpDUnitTest {
+public class ExportLogsOverHttpDUnitTest extends ExportStatsDUnitTest {
 
   @Rule
   public TemporaryFolder temporaryFolder = new TemporaryFolder();
 
-  @ClassRule
-  public static LocatorServerStartupRule lsRule = new LocatorServerStartupRule();
-
-  @ClassRule
-  public static GfshShellConnectionRule gfshConnector = new GfshShellConnectionRule();
-
-  private static int jmxPort, httpPort;
-  private static Properties locatorProperties;
-  private static Set<String> expectedZipEntries = new HashSet<>();
-
-  @BeforeClass
-  public static void beforeClass() throws Exception {
-    int[] ports = AvailablePortHelper.getRandomAvailableTCPPorts(2);
-    httpPort = ports[0];
-    jmxPort = ports[1];
-    locatorProperties = new Properties();
-    locatorProperties.setProperty(HTTP_SERVICE_BIND_ADDRESS, "localhost");
-    locatorProperties.setProperty(HTTP_SERVICE_PORT, httpPort + "");
-    locatorProperties.setProperty(JMX_MANAGER_PORT, jmxPort + "");
-
-    // start the locator in vm0 and then connect to it over http
-    Locator locator = lsRule.startLocatorVM(0, locatorProperties);
-    lsRule.startServerVM(1, locator.getPort());
-    gfshConnector.connectAndVerify(httpPort, GfshShellConnectionRule.PortType.http);
-
-    expectedZipEntries = Sets.newHashSet("locator-0/locator-0.log", "server-1/server-1.log");
-  }
-
-  @Test
-  public void testExportWithNoDir() throws Exception {
-    // export the logs
-    gfshConnector.executeCommand("export logs");
-    // verify that the message contains a path to the user.dir
-    String message = gfshConnector.getGfshOutput();
-    assertThat(message).contains("Logs exported to: ");
-    assertThat(message).contains(System.getProperty("user.dir"));
-
-    String zipPath = getZipPathFromCommandResult(message);
-    verifyZipContent(zipPath);
+  @Override
+  public void connectIfNeeded() throws Exception {
+    if (!connector.isConnected())
+      connector.connect(httpPort, GfshShellConnectionRule.PortType.http);
   }
 
   @Test
   public void testExportWithDir() throws Exception {
+    connectIfNeeded();
     File dir = temporaryFolder.newFolder();
     // export the logs
-    gfshConnector.executeCommand("export logs --dir=" + dir.getAbsolutePath());
+    connector.executeCommand("export logs --dir=" + dir.getAbsolutePath());
     // verify that the message contains a path to the user.dir
-    String message = gfshConnector.getGfshOutput();
+    String message = connector.getGfshOutput();
     assertThat(message).contains("Logs exported to: ");
     assertThat(message).contains(dir.getAbsolutePath());
 
     String zipPath = getZipPathFromCommandResult(message);
-    verifyZipContent(zipPath);
-  }
-
-  private void verifyZipContent(String zipPath) throws Exception {
-    Set<String> actualZipEnries =
+    Set<String> actualZipEntries =
         new ZipFile(zipPath).stream().map(ZipEntry::getName).collect(Collectors.toSet());
 
-    assertThat(actualZipEnries).isEqualTo(expectedZipEntries);
+    assertThat(actualZipEntries).isEqualTo(expectedZipEntries);
   }
 
-  private String getZipPathFromCommandResult(String message) {
+  protected String getZipPathFromCommandResult(String message) {
     return message.replaceAll("Logs exported to: ", "").trim();
   }
 }


Mime
View raw message