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

brandonwilliams pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/cassandra.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 26098da  Add unit tests: tpstats, gossipinfo, en/disablebinary
26098da is described below

commit 26098da5d8fe39260b1b5e3a724f3b4e0b7719cb
Author: Bereng <[email protected]>
AuthorDate: Wed Oct 28 07:37:09 2020 +0100

    Add unit tests: tpstats, gossipinfo, en/disablebinary
    
    Patch by Berenguer Blasi, reviewed by brandonwilliams for
    CASSANDRA-16230
---
 .../tools/nodetool/stats/TpStatsHolder.java        |   8 +-
 .../test/NodeToolEnableDisableBinaryTest.java      | 168 +++++++++++++++++
 .../cassandra/tools/NodeToolGossipInfoTest.java    | 130 +++++++++++++
 .../cassandra/tools/NodeToolTPStatsTest.java       | 210 +++++++++++++++++++++
 4 files changed, 514 insertions(+), 2 deletions(-)

diff --git 
a/src/java/org/apache/cassandra/tools/nodetool/stats/TpStatsHolder.java 
b/src/java/org/apache/cassandra/tools/nodetool/stats/TpStatsHolder.java
index c641691..38011ba 100644
--- a/src/java/org/apache/cassandra/tools/nodetool/stats/TpStatsHolder.java
+++ b/src/java/org/apache/cassandra/tools/nodetool/stats/TpStatsHolder.java
@@ -18,6 +18,7 @@
 
 package org.apache.cassandra.tools.nodetool.stats;
 
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -38,7 +39,7 @@ public class TpStatsHolder implements StatsHolder
         HashMap<String, Object> result = new HashMap<>();
         HashMap<String, Map<String, Object>> threadPools = new HashMap<>();
         HashMap<String, Object> droppedMessage = new HashMap<>();
-        HashMap<String, Double[]> waitLatencies = new HashMap<>();
+        HashMap<String, String[]> waitLatencies = new HashMap<>();
 
         for (Map.Entry<String, String> tp : probe.getThreadPools().entries())
         {
@@ -57,7 +58,10 @@ public class TpStatsHolder implements StatsHolder
             droppedMessage.put(entry.getKey(), entry.getValue());
             try
             {
-                waitLatencies.put(entry.getKey(), 
probe.metricPercentilesAsArray(probe.getMessagingQueueWaitMetrics(entry.getKey())));
+                String[] strValues = (String[]) 
Arrays.stream(probe.metricPercentilesAsArray(probe.getMessagingQueueWaitMetrics(entry.getKey())))
+                                                      .map(D -> D.toString())
+                                                      .toArray();
+                waitLatencies.put(entry.getKey(), strValues);
             }
             catch (RuntimeException e)
             {
diff --git 
a/test/distributed/org/apache/cassandra/distributed/test/NodeToolEnableDisableBinaryTest.java
 
b/test/distributed/org/apache/cassandra/distributed/test/NodeToolEnableDisableBinaryTest.java
new file mode 100644
index 0000000..d690294
--- /dev/null
+++ 
b/test/distributed/org/apache/cassandra/distributed/test/NodeToolEnableDisableBinaryTest.java
@@ -0,0 +1,168 @@
+/*
+ * 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.cassandra.distributed.test;
+
+import java.io.IOException;
+
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.datastax.driver.core.Session;
+import org.apache.cassandra.distributed.api.ICluster;
+import org.apache.cassandra.tools.ToolRunner;
+import org.apache.cassandra.tools.ToolRunner.ToolResult;
+import org.assertj.core.api.Assertions;
+
+import static org.apache.cassandra.distributed.api.Feature.GOSSIP;
+import static org.apache.cassandra.distributed.api.Feature.NATIVE_PROTOCOL;
+import static org.apache.cassandra.distributed.api.Feature.NETWORK;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class NodeToolEnableDisableBinaryTest extends TestBaseImpl
+{
+    private static ICluster cluster;
+
+    @Before
+    public void setupEnv() throws IOException
+    {
+        if (cluster == null)
+            cluster = init(builder().withNodes(1)
+                                    .withConfig(config -> config.with(NETWORK, 
GOSSIP, NATIVE_PROTOCOL))
+                                    .start());
+    }
+
+    @AfterClass
+    public static void teardownEnv() throws Exception
+    {
+        cluster.close();
+    }
+
+    @Test
+    public void testMaybeChangeDocs()
+    {
+        // If you added, modified options or help, please update docs if 
necessary
+
+        ToolResult tool = ToolRunner.invokeNodetoolJvmDtest(cluster.get(1), 
"help", "disablebinary");
+        String help =   "NAME\n" + 
+                        "        nodetool disablebinary - Disable native 
transport (binary protocol)\n" + 
+                        "\n" + 
+                        "SYNOPSIS\n" + 
+                        "        nodetool [(-h <host> | --host <host>)] [(-p 
<port> | --port <port>)]\n" + 
+                        "                [(-pp | --print-port)] [(-pw 
<password> | --password <password>)]\n" + 
+                        "                [(-pwf <passwordFilePath> | 
--password-file <passwordFilePath>)]\n" + 
+                        "                [(-u <username> | --username 
<username>)] disablebinary\n" + 
+                        "\n" + 
+                        "OPTIONS\n" + 
+                        "        -h <host>, --host <host>\n" + 
+                        "            Node hostname or ip address\n" + 
+                        "\n" + 
+                        "        -p <port>, --port <port>\n" + 
+                        "            Remote jmx agent port number\n" + 
+                        "\n" + 
+                        "        -pp, --print-port\n" + 
+                        "            Operate in 4.0 mode with hosts 
disambiguated by port number\n" + 
+                        "\n" + 
+                        "        -pw <password>, --password <password>\n" + 
+                        "            Remote jmx agent password\n" + 
+                        "\n" + 
+                        "        -pwf <passwordFilePath>, --password-file 
<passwordFilePath>\n" + 
+                        "            Path to the JMX password file\n" + 
+                        "\n" + 
+                        "        -u <username>, --username <username>\n" + 
+                        "            Remote jmx agent username\n" + 
+                        "\n" + 
+                        "\n";
+        Assertions.assertThat(tool.getStdout()).isEqualTo(help);
+
+        tool = ToolRunner.invokeNodetoolJvmDtest(cluster.get(1), "help", 
"enablebinary");
+        help =  "NAME\n" + 
+                "        nodetool enablebinary - Reenable native transport 
(binary protocol)\n" + 
+                "\n" + 
+                "SYNOPSIS\n" + 
+                "        nodetool [(-h <host> | --host <host>)] [(-p <port> | 
--port <port>)]\n" + 
+                "                [(-pp | --print-port)] [(-pw <password> | 
--password <password>)]\n" + 
+                "                [(-pwf <passwordFilePath> | --password-file 
<passwordFilePath>)]\n" + 
+                "                [(-u <username> | --username <username>)] 
enablebinary\n" + 
+                "\n" + 
+                "OPTIONS\n" + 
+                "        -h <host>, --host <host>\n" + 
+                "            Node hostname or ip address\n" + 
+                "\n" + 
+                "        -p <port>, --port <port>\n" + 
+                "            Remote jmx agent port number\n" + 
+                "\n" + 
+                "        -pp, --print-port\n" + 
+                "            Operate in 4.0 mode with hosts disambiguated by 
port number\n" + 
+                "\n" + 
+                "        -pw <password>, --password <password>\n" + 
+                "            Remote jmx agent password\n" + 
+                "\n" + 
+                "        -pwf <passwordFilePath>, --password-file 
<passwordFilePath>\n" + 
+                "            Path to the JMX password file\n" + 
+                "\n" + 
+                "        -u <username>, --username <username>\n" + 
+                "            Remote jmx agent username\n" + 
+                "\n" + 
+                "\n";
+        Assertions.assertThat(tool.getStdout()).isEqualTo(help);
+    }
+
+    @Test
+    public void testEnableDisableBinary() throws Throwable
+    {
+        // We can connect
+        assertTrue(canConnect());
+
+        // We can't connect after disabling
+        ToolResult tool = ToolRunner.invokeNodetoolJvmDtest(cluster.get(1), 
"disablebinary");
+        Assertions.assertThat(tool.getStdout()).containsIgnoringCase("Stop 
listening for CQL clients");
+        assertTrue(tool.getCleanedStderr().isEmpty());
+        assertEquals(0, tool.getExitCode());
+        assertFalse(canConnect());
+
+        // We can connect after re-enabling
+        tool = ToolRunner.invokeNodetoolJvmDtest(cluster.get(1), 
"enablebinary");
+        Assertions.assertThat(tool.getStdout()).containsIgnoringCase("Starting 
listening for CQL clients");
+        assertTrue(tool.getCleanedStderr().isEmpty());
+        assertEquals(0, tool.getExitCode());
+        assertTrue(canConnect());
+    }
+
+    private boolean canConnect()
+    {
+        boolean canConnect = false;
+        try(com.datastax.driver.core.Cluster c = 
com.datastax.driver.core.Cluster.builder()
+                                                                               
  .addContactPoint("127.0.0.1")
+                                                                               
  .build();
+            Session s = c.connect("system_schema"))
+        {
+            s.execute("SELECT * FROM system_schema.aggregates");
+            canConnect = true;
+        }
+        catch(Exception e)
+        {
+            canConnect = false;
+        }
+
+        return canConnect;
+    }
+}
diff --git a/test/unit/org/apache/cassandra/tools/NodeToolGossipInfoTest.java 
b/test/unit/org/apache/cassandra/tools/NodeToolGossipInfoTest.java
new file mode 100644
index 0000000..e69f860
--- /dev/null
+++ b/test/unit/org/apache/cassandra/tools/NodeToolGossipInfoTest.java
@@ -0,0 +1,130 @@
+/*
+ * 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.cassandra.tools;
+
+import java.io.IOException;
+
+import org.apache.commons.lang3.StringUtils;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.apache.cassandra.OrderedJUnit4ClassRunner;
+import org.apache.cassandra.cql3.CQLTester;
+import org.apache.cassandra.net.Message;
+import org.apache.cassandra.net.MessagingService;
+import org.apache.cassandra.net.NoPayload;
+import org.apache.cassandra.tools.ToolRunner.ToolResult;
+import org.apache.cassandra.utils.FBUtilities;
+import org.assertj.core.api.Assertions;
+
+import static org.apache.cassandra.net.Verb.ECHO_REQ;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+@RunWith(OrderedJUnit4ClassRunner.class)
+public class NodeToolGossipInfoTest extends CQLTester
+{
+    private static NodeProbe probe;
+
+    @BeforeClass
+    public static void setup() throws Exception
+    {
+        requireNetwork();
+        startJMXServer();
+        probe = new NodeProbe(jmxHost, jmxPort);
+    }
+
+    @AfterClass
+    public static void teardown() throws IOException
+    {
+        probe.close();
+    }
+
+    @Test
+    public void testMaybeChangeDocs()
+    {
+        // If you added, modified options or help, please update docs if 
necessary
+        ToolResult tool = ToolRunner.invokeNodetool("help", "gossipinfo");
+        String help =   "NAME\n" + 
+                        "        nodetool gossipinfo - Shows the gossip 
information for the cluster\n" + 
+                        "\n" + 
+                        "SYNOPSIS\n" + 
+                        "        nodetool [(-h <host> | --host <host>)] [(-p 
<port> | --port <port>)]\n" + 
+                        "                [(-pp | --print-port)] [(-pw 
<password> | --password <password>)]\n" + 
+                        "                [(-pwf <passwordFilePath> | 
--password-file <passwordFilePath>)]\n" + 
+                        "                [(-u <username> | --username 
<username>)] gossipinfo\n" + 
+                        "\n" + 
+                        "OPTIONS\n" + 
+                        "        -h <host>, --host <host>\n" + 
+                        "            Node hostname or ip address\n" + 
+                        "\n" + 
+                        "        -p <port>, --port <port>\n" + 
+                        "            Remote jmx agent port number\n" + 
+                        "\n" + 
+                        "        -pp, --print-port\n" + 
+                        "            Operate in 4.0 mode with hosts 
disambiguated by port number\n" + 
+                        "\n" + 
+                        "        -pw <password>, --password <password>\n" + 
+                        "            Remote jmx agent password\n" + 
+                        "\n" + 
+                        "        -pwf <passwordFilePath>, --password-file 
<passwordFilePath>\n" + 
+                        "            Path to the JMX password file\n" + 
+                        "\n" + 
+                        "        -u <username>, --username <username>\n" + 
+                        "            Remote jmx agent username\n" + 
+                        "\n" + 
+                        "\n";
+        Assertions.assertThat(tool.getStdout()).isEqualTo(help);
+    }
+
+    @Test
+    public void testTPStats() throws Throwable
+    {
+        ToolResult tool = ToolRunner.invokeNodetool("gossipinfo");
+        Assertions.assertThat(tool.getStdout()).contains("/127.0.0.1");
+        
Assertions.assertThat(tool.getStdout()).containsPattern("heartbeat:[0-9]+");
+        
Assertions.assertThat(tool.getStdout()).containsPattern("STATUS:[0-9]+:NORMAL,.+");
+        Assertions.assertThat(tool.getStdout()).containsPattern("SCHEMA:.+");
+        
Assertions.assertThat(tool.getStdout()).containsPattern("DC:[0-9]+:datacenter1");
+        
Assertions.assertThat(tool.getStdout()).containsPattern("RACK:[0-9]+:rack1");
+        
Assertions.assertThat(tool.getStdout()).containsPattern("RELEASE_VERSION:.+");
+        
Assertions.assertThat(tool.getStdout()).containsPattern("RPC_ADDRESS:[0-9]+:127.0.0.1");
+        
Assertions.assertThat(tool.getStdout()).containsPattern("NET_VERSION:[0-9]+:.+");
+        
Assertions.assertThat(tool.getStdout()).containsPattern("HOST_ID:[0-9]+:.+");
+        
Assertions.assertThat(tool.getStdout()).containsPattern("NATIVE_ADDRESS_AND_PORT:[0-9]+:127.0.0.1:[0-9]+");
+        
Assertions.assertThat(tool.getStdout()).containsPattern("STATUS_WITH_PORT:[0-9]+:NORMAL,.+");
+        
Assertions.assertThat(tool.getStdout()).containsPattern("TOKENS:[0-9]+:<hidden>");
+        assertTrue(tool.getCleanedStderr().isEmpty());
+        assertEquals(0, tool.getExitCode());
+
+        // Make sure heartbeats are detected
+        Message<NoPayload> echoMessageOut = Message.out(ECHO_REQ, 
NoPayload.noPayload);
+        MessagingService.instance().send(echoMessageOut, 
FBUtilities.getBroadcastAddressAndPort());
+
+        String origHeartbeatCount = 
StringUtils.substringBetween(tool.getStdout(), "heartbeat:", "\n");
+        tool = ToolRunner.invokeNodetool("gossipinfo");
+        assertTrue(tool.getCleanedStderr().isEmpty());
+        assertEquals(0, tool.getExitCode());
+        String newHeartbeatCount = 
StringUtils.substringBetween(tool.getStdout(), "heartbeat:", "\n");
+        assertTrue(Integer.parseInt(origHeartbeatCount) < 
Integer.parseInt(newHeartbeatCount));
+    }
+}
diff --git a/test/unit/org/apache/cassandra/tools/NodeToolTPStatsTest.java 
b/test/unit/org/apache/cassandra/tools/NodeToolTPStatsTest.java
new file mode 100644
index 0000000..e437fc1
--- /dev/null
+++ b/test/unit/org/apache/cassandra/tools/NodeToolTPStatsTest.java
@@ -0,0 +1,210 @@
+/*
+ * 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.cassandra.tools;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.lang3.tuple.Pair;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.cassandra.OrderedJUnit4ClassRunner;
+import org.apache.cassandra.cql3.CQLTester;
+import org.apache.cassandra.net.Message;
+import org.apache.cassandra.net.MessagingService;
+import org.apache.cassandra.net.NoPayload;
+import org.apache.cassandra.tools.ToolRunner.ToolResult;
+import org.apache.cassandra.utils.FBUtilities;
+import org.assertj.core.api.Assertions;
+import org.yaml.snakeyaml.Yaml;
+
+import static org.apache.cassandra.net.Verb.ECHO_REQ;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+
+@RunWith(OrderedJUnit4ClassRunner.class)
+public class NodeToolTPStatsTest extends CQLTester
+{
+    private static NodeProbe probe;
+
+    @BeforeClass
+    public static void setup() throws Exception
+    {
+        requireNetwork();
+        startJMXServer();
+        probe = new NodeProbe(jmxHost, jmxPort);
+    }
+
+    @AfterClass
+    public static void teardown() throws IOException
+    {
+        probe.close();
+    }
+
+    @Test
+    public void testMaybeChangeDocs()
+    {
+        // If you added, modified options or help, please update docs if 
necessary
+        ToolResult tool = ToolRunner.invokeNodetool("help", "tpstats");
+        String help =   "NAME\n" + 
+                        "        nodetool tpstats - Print usage statistics of 
thread pools\n" + 
+                        "\n" + 
+                        "SYNOPSIS\n" + 
+                        "        nodetool [(-h <host> | --host <host>)] [(-p 
<port> | --port <port>)]\n" + 
+                        "                [(-pp | --print-port)] [(-pw 
<password> | --password <password>)]\n" + 
+                        "                [(-pwf <passwordFilePath> | 
--password-file <passwordFilePath>)]\n" + 
+                        "                [(-u <username> | --username 
<username>)] tpstats\n" + 
+                        "                [(-F <format> | --format 
<format>)]\n" + 
+                        "\n" + 
+                        "OPTIONS\n" + 
+                        "        -F <format>, --format <format>\n" + 
+                        "            Output format (json, yaml)\n" + 
+                        "\n" + 
+                        "        -h <host>, --host <host>\n" + 
+                        "            Node hostname or ip address\n" + 
+                        "\n" + 
+                        "        -p <port>, --port <port>\n" + 
+                        "            Remote jmx agent port number\n" + 
+                        "\n" + 
+                        "        -pp, --print-port\n" + 
+                        "            Operate in 4.0 mode with hosts 
disambiguated by port number\n" + 
+                        "\n" + 
+                        "        -pw <password>, --password <password>\n" + 
+                        "            Remote jmx agent password\n" + 
+                        "\n" + 
+                        "        -pwf <passwordFilePath>, --password-file 
<passwordFilePath>\n" + 
+                        "            Path to the JMX password file\n" + 
+                        "\n" + 
+                        "        -u <username>, --username <username>\n" + 
+                        "            Remote jmx agent username\n" +  
+                        "\n" + 
+                        "\n";
+        Assertions.assertThat(tool.getStdout()).isEqualTo(help);
+    }
+
+    @Test
+    public void testTPStats() throws Throwable
+    {
+        ToolResult tool = ToolRunner.invokeNodetool("tpstats");
+        Assertions.assertThat(tool.getStdout()).containsIgnoringCase("Pool 
Name                    Active Pending Completed Blocked All time blocked");
+        
Assertions.assertThat(tool.getStdout()).containsIgnoringCase("Latencies waiting 
in queue (micros) per dropped message types");
+        assertTrue(tool.getCleanedStderr().isEmpty());
+        assertEquals(0, tool.getExitCode());
+
+        // Does inserting data alter tpstats?
+        String nonZeroedThreadsRegExp = "((?m)\\D.*[1-9].*)";
+        ArrayList<String> origStats = 
getAllGroupMatches(nonZeroedThreadsRegExp, tool.getStdout());
+        Collections.sort(origStats);
+
+        createTable("CREATE TABLE %s (pk int, c int, PRIMARY KEY(pk))");
+        execute("INSERT INTO %s (pk, c) VALUES (?, ?)", 1, 1);
+        tool = ToolRunner.invokeNodetool("tpstats");
+        assertTrue(tool.getCleanedStderr().isEmpty());
+        assertEquals(0, tool.getExitCode());
+        ArrayList<String> newStats = 
getAllGroupMatches(nonZeroedThreadsRegExp, tool.getStdout());
+        Collections.sort(newStats);
+
+        assertNotEquals(origStats, newStats);
+
+        // Does sending a message alter Gossip & ECHO stats?
+        String origGossip = getAllGroupMatches("((?m)GossipStage.*)", 
tool.getStdout()).get(0);
+        
Assertions.assertThat(tool.getStdout()).doesNotContainPattern("ECHO_REQ\\D.*[1-9].*");
+        
Assertions.assertThat(tool.getStdout()).doesNotContainPattern("ECHO_RSP\\D.*[1-9].*");
+
+        Message<NoPayload> echoMessageOut = Message.out(ECHO_REQ, 
NoPayload.noPayload);
+        MessagingService.instance().send(echoMessageOut, 
FBUtilities.getBroadcastAddressAndPort());
+
+        tool = ToolRunner.invokeNodetool("tpstats");
+        assertTrue(tool.getCleanedStderr().isEmpty());
+        assertEquals(0, tool.getExitCode());
+        String newGossip = getAllGroupMatches("((?m)GossipStage.*)", 
tool.getStdout()).get(0);
+
+        assertNotEquals(origGossip, newGossip);
+        
Assertions.assertThat(tool.getStdout()).containsPattern("ECHO_REQ\\D.*[1-9].*");
+        
Assertions.assertThat(tool.getStdout()).containsPattern("ECHO_RSP\\D.*[1-9].*");
+    }
+
+    @Test
+    public void testFromatArg() throws Throwable
+    {
+        Arrays.asList(Pair.of("-F", "json"), Pair.of("--format", 
"json")).forEach(arg -> {
+            ToolResult tool = ToolRunner.invokeNodetool("tpstats", 
arg.getLeft(), arg.getRight());
+            assertTrue(isJSONString(tool.getStdout()));
+            assertTrue(tool.getCleanedStderr().isEmpty());
+            assertEquals(0, tool.getExitCode());
+        });
+
+        Arrays.asList( Pair.of("-F", "yaml"), Pair.of("--format", 
"yaml")).forEach(arg -> {
+            ToolResult tool = ToolRunner.invokeNodetool("tpstats", 
arg.getLeft(), arg.getRight());
+            assertTrue(isYAMLString(tool.getStdout()));
+            assertTrue(tool.getCleanedStderr().isEmpty());
+            assertEquals(0, tool.getExitCode());
+        });
+    }
+
+    public static boolean isJSONString(String str)
+    {
+        try
+        {
+            ObjectMapper mapper = new ObjectMapper();
+            mapper.readTree(str);
+            return true;
+        }
+        catch(IOException e)
+        {
+            return false;
+        }
+    }
+
+    public static boolean isYAMLString(String str)
+    {
+        try
+        {
+            Yaml yaml = new Yaml();
+            yaml.load(str);
+            return true;
+        }
+        catch(Exception e)
+        {
+            return false;
+        }
+    }
+
+    private ArrayList<String> getAllGroupMatches(String regExp, String in)
+    {
+        Pattern pattern = Pattern.compile(regExp);
+        Matcher m = pattern.matcher(in);
+
+        ArrayList<String> matches = new ArrayList<>();
+        while (m.find())
+            matches.add(m.group(1));
+
+        return matches;
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to