You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by ed...@apache.org on 2021/02/03 14:37:22 UTC
[cassandra] branch trunk updated: Fix nodetool ring, status output
when DNS resolution or port printing are in use Patch by Adam Holmberg and
Scott Wolfenhaut;
reviewed by Berenguer Blasi, Brandon Williams and Ekaterina Dimitrova for
CASSANDRA-16283
This is an automated email from the ASF dual-hosted git repository.
edimitrova 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 b61860c Fix nodetool ring, status output when DNS resolution or port printing are in use Patch by Adam Holmberg and Scott Wolfenhaut; reviewed by Berenguer Blasi, Brandon Williams and Ekaterina Dimitrova for CASSANDRA-16283
b61860c is described below
commit b61860c76e9cf1eebfb7d29dc4f4420955f62bb4
Author: wolfenha <wo...@adobe.com>
AuthorDate: Thu Dec 10 11:19:40 2020 -0500
Fix nodetool ring, status output when DNS resolution or port printing are in use
Patch by Adam Holmberg and Scott Wolfenhaut; reviewed by Berenguer Blasi, Brandon Williams and Ekaterina Dimitrova for CASSANDRA-16283
---
CHANGES.txt | 1 +
.../org/apache/cassandra/locator/SimpleSnitch.java | 3 +-
.../apache/cassandra/service/StorageService.java | 2 +-
.../cassandra/tools/nodetool/HostStatWithPort.java | 2 +-
.../org/apache/cassandra/tools/nodetool/Ring.java | 228 +++++----------------
.../tools/nodetool/SetHostStatWithPort.java | 2 +-
.../apache/cassandra/tools/nodetool/Status.java | 31 +--
.../cassandra/distributed/test/NodeToolTest.java | 6 +-
.../apache/cassandra/tools/nodetool/RingTest.java} | 139 +++++++------
.../cassandra/tools/nodetool/StatusTest.java | 93 +++++++++
.../nodetool/stats/NodetoolTableStatsTest.java | 12 --
11 files changed, 246 insertions(+), 273 deletions(-)
diff --git a/CHANGES.txt b/CHANGES.txt
index 92b0e83..ba23707 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
4.0-beta5
+ * Fix nodetool ring, status output when DNS resolution or port printing are in use (CASSANDRA-16283)
* Upgrade Jacoco to 0.8.6 (for Java 11 support) (CASSANDRA-16365)
* Move excessive repair debug loggings to trace level (CASSANDRA-16406)
* Restore validation of each message's protocol version (CASSANDRA-16374)
diff --git a/src/java/org/apache/cassandra/locator/SimpleSnitch.java b/src/java/org/apache/cassandra/locator/SimpleSnitch.java
index f26375a..f9bf215 100644
--- a/src/java/org/apache/cassandra/locator/SimpleSnitch.java
+++ b/src/java/org/apache/cassandra/locator/SimpleSnitch.java
@@ -25,10 +25,11 @@ package org.apache.cassandra.locator;
public class SimpleSnitch extends AbstractEndpointSnitch
{
public static final String DATA_CENTER_NAME = "datacenter1";
+ public static final String RACK_NAME = "rack1";
public String getRack(InetAddressAndPort endpoint)
{
- return "rack1";
+ return RACK_NAME;
}
public String getDatacenter(InetAddressAndPort endpoint)
diff --git a/src/java/org/apache/cassandra/service/StorageService.java b/src/java/org/apache/cassandra/service/StorageService.java
index 1b180c0..da0c8ea 100644
--- a/src/java/org/apache/cassandra/service/StorageService.java
+++ b/src/java/org/apache/cassandra/service/StorageService.java
@@ -5170,7 +5170,7 @@ public class StorageService extends NotificationBroadcasterSupport implements IE
{
LinkedHashMap<InetAddressAndPort, Float> result = getEffectiveOwnership(keyspace);
LinkedHashMap<String, Float> asStrings = new LinkedHashMap<>();
- result.entrySet().stream().forEachOrdered(entry -> asStrings.put(entry.getKey().toString(), entry.getValue()));
+ result.entrySet().stream().forEachOrdered(entry -> asStrings.put(entry.getKey().getHostAddressAndPort(), entry.getValue()));
return asStrings;
}
diff --git a/src/java/org/apache/cassandra/tools/nodetool/HostStatWithPort.java b/src/java/org/apache/cassandra/tools/nodetool/HostStatWithPort.java
index 4849fd1..9cff725 100644
--- a/src/java/org/apache/cassandra/tools/nodetool/HostStatWithPort.java
+++ b/src/java/org/apache/cassandra/tools/nodetool/HostStatWithPort.java
@@ -42,6 +42,6 @@ public class HostStatWithPort extends HostStat
return resolveIp ?
endpointWithPort.address.getHostName() + ':' + endpointWithPort.port :
- endpointWithPort.toString();
+ endpointWithPort.getHostAddressAndPort();
}
}
diff --git a/src/java/org/apache/cassandra/tools/nodetool/Ring.java b/src/java/org/apache/cassandra/tools/nodetool/Ring.java
index 134c85d..ccc7912 100644
--- a/src/java/org/apache/cassandra/tools/nodetool/Ring.java
+++ b/src/java/org/apache/cassandra/tools/nodetool/Ring.java
@@ -23,7 +23,6 @@ import io.airlift.airline.Command;
import io.airlift.airline.Option;
import java.io.PrintStream;
-import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.DecimalFormat;
import java.util.ArrayList;
@@ -34,6 +33,7 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import org.apache.cassandra.locator.EndpointSnitchInfoMBean;
import org.apache.cassandra.tools.NodeProbe;
import org.apache.cassandra.tools.NodeTool;
import org.apache.cassandra.tools.NodeTool.NodeToolCmd;
@@ -49,192 +49,76 @@ public class Ring extends NodeToolCmd
@Option(title = "resolve_ip", name = {"-r", "--resolve-ip"}, description = "Show node domain names instead of IPs")
private boolean resolveIp = false;
+ private PrintStream out;
+ private EndpointSnitchInfoMBean epSnitchInfo;
+ private Collection<String> liveNodes, deadNodes, joiningNodes, leavingNodes, movingNodes;
+ private Map<String, String> loadMap;
+
@Override
public void execute(NodeProbe probe)
{
- PrintStream out = probe.output().out;
- try
+ out = probe.output().out;
+ liveNodes = probe.getLiveNodes(true);
+ deadNodes = probe.getUnreachableNodes(true);
+ joiningNodes = probe.getJoiningNodes(true);
+ leavingNodes = probe.getLeavingNodes(true);
+ movingNodes = probe.getMovingNodes(true);
+ loadMap = probe.getLoadMap(true);
+ epSnitchInfo = probe.getEndpointSnitchInfoProxy();
+
+ Map<String, String> tokensToEndpoints = probe.getTokenToEndpointMap(true);
+ LinkedHashMultimap<String, String> endpointsToTokens = LinkedHashMultimap.create();
+ boolean haveVnodes = false;
+ for (Map.Entry<String, String> entry : tokensToEndpoints.entrySet())
{
- Map<String, String> tokensToEndpoints = probe.getTokenToEndpointMap(printPort);
- LinkedHashMultimap<String, String> endpointsToTokens = LinkedHashMultimap.create();
- boolean haveVnodes = false;
- for (Map.Entry<String, String> entry : tokensToEndpoints.entrySet())
- {
- haveVnodes |= endpointsToTokens.containsKey(entry.getValue());
- endpointsToTokens.put(entry.getValue(), entry.getKey());
- }
-
- int maxAddressLength = Collections.max(endpointsToTokens.keys(), new Comparator<String>()
- {
- @Override
- public int compare(String first, String second)
- {
- return Integer.compare(first.length(), second.length());
- }
- }).length();
-
- String formatPlaceholder = "%%-%ds %%-12s%%-7s%%-8s%%-16s%%-20s%%-44s%%n";
- String format = format(formatPlaceholder, maxAddressLength);
-
- StringBuilder errors = new StringBuilder();
- boolean showEffectiveOwnership = true;
-
- if (printPort)
- {
- // Calculate per-token ownership of the ring
- Map<String, Float> ownerships;
- try
- {
- ownerships = probe.effectiveOwnershipWithPort(keyspace);
- }
- catch (IllegalStateException ex)
- {
- ownerships = probe.getOwnershipWithPort();
- errors.append("Note: ").append(ex.getMessage()).append("%n");
- showEffectiveOwnership = false;
- }
- catch (IllegalArgumentException ex)
- {
- out.printf("%nError: %s%n", ex.getMessage());
- return;
- }
-
-
- out.println();
- for (Entry<String, SetHostStatWithPort> entry : NodeTool.getOwnershipByDcWithPort(probe, resolveIp, tokensToEndpoints, ownerships).entrySet())
- printDc(probe, format, entry.getKey(), endpointsToTokens, entry.getValue(), showEffectiveOwnership);
-
- if (haveVnodes)
- {
- out.println(" Warning: \"nodetool ring\" is used to output all the tokens of a node.");
- out.println(" To view status related info of a node use \"nodetool status\" instead.\n");
- }
-
- out.printf("%n " + errors.toString());
- }
- else
- {
- // Calculate per-token ownership of the ring
- Map<InetAddress, Float> ownerships;
- try
- {
- ownerships = probe.effectiveOwnership(keyspace);
- }
- catch (IllegalStateException ex)
- {
- ownerships = probe.getOwnership();
- errors.append("Note: ").append(ex.getMessage()).append("%n");
- showEffectiveOwnership = false;
- }
- catch (IllegalArgumentException ex)
- {
- out.printf("%nError: %s%n", ex.getMessage());
- return;
- }
+ haveVnodes |= endpointsToTokens.containsKey(entry.getValue());
+ endpointsToTokens.put(entry.getValue(), entry.getKey());
+ }
+ int maxAddressLength = Collections.max(endpointsToTokens.keys(),
+ Comparator.comparingInt(String::length)).length();
- out.println();
- for (Entry<String, SetHostStat> entry : NodeTool.getOwnershipByDc(probe, resolveIp, tokensToEndpoints, ownerships).entrySet())
- printDc(probe, format, entry.getKey(), endpointsToTokens, entry.getValue(), showEffectiveOwnership);
+ String formatPlaceholder = "%%-%ds %%-12s%%-7s%%-8s%%-16s%%-20s%%-44s%%n";
+ String format = format(formatPlaceholder, maxAddressLength);
- if (haveVnodes)
- {
- out.println(" Warning: \"nodetool ring\" is used to output all the tokens of a node.");
- out.println(" To view status related info of a node use \"nodetool status\" instead.\n");
- }
+ StringBuilder errors = new StringBuilder();
+ boolean showEffectiveOwnership = true;
- out.printf("%n " + errors.toString());
- }
- } catch (Exception e)
+ // Calculate per-token ownership of the ring
+ Map<String, Float> ownerships;
+ try
{
- e.printStackTrace();
- throw e;
+ ownerships = probe.effectiveOwnershipWithPort(keyspace);
}
- }
-
- private void printDc(NodeProbe probe, String format,
- String dc,
- LinkedHashMultimap<String, String> endpointsToTokens,
- SetHostStat hoststats,boolean showEffectiveOwnership)
- {
- PrintStream out = probe.output().out;
- Collection<String> liveNodes = probe.getLiveNodes(false);
- Collection<String> deadNodes = probe.getUnreachableNodes(false);
- Collection<String> joiningNodes = probe.getJoiningNodes(false);
- Collection<String> leavingNodes = probe.getLeavingNodes(false);
- Collection<String> movingNodes = probe.getMovingNodes(false);
- Map<String, String> loadMap = probe.getLoadMap(false);
-
- out.println("Datacenter: " + dc);
- out.println("==========");
-
- // get the total amount of replicas for this dc and the last token in this dc's ring
- List<String> tokens = new ArrayList<>();
- String lastToken = "";
-
- for (HostStat stat : hoststats)
+ catch (IllegalStateException ex)
{
- tokens.addAll(endpointsToTokens.get(stat.endpoint.getHostAddress()));
- lastToken = tokens.get(tokens.size() - 1);
+ ownerships = probe.getOwnershipWithPort();
+ errors.append("Note: ").append(ex.getMessage()).append("%n");
+ showEffectiveOwnership = false;
}
-
- out.printf(format, "Address", "Rack", "Status", "State", "Load", "Owns", "Token");
-
- if (hoststats.size() > 1)
- out.printf(format, "", "", "", "", "", "", lastToken);
- else
- out.println();
-
- for (HostStat stat : hoststats)
+ catch (IllegalArgumentException ex)
{
- String endpoint = stat.endpoint.getHostAddress();
- String rack;
- try
- {
- rack = probe.getEndpointSnitchInfoProxy().getRack(endpoint);
- }
- catch (UnknownHostException e)
- {
- rack = "Unknown";
- }
-
- String status = liveNodes.contains(endpoint)
- ? "Up"
- : deadNodes.contains(endpoint)
- ? "Down"
- : "?";
-
- String state = "Normal";
+ out.printf("%nError: %s%n", ex.getMessage());
+ return;
+ }
- if (joiningNodes.contains(endpoint))
- state = "Joining";
- else if (leavingNodes.contains(endpoint))
- state = "Leaving";
- else if (movingNodes.contains(endpoint))
- state = "Moving";
+ out.println();
+ for (Entry<String, SetHostStatWithPort> entry : NodeTool.getOwnershipByDcWithPort(probe, resolveIp, tokensToEndpoints, ownerships).entrySet())
+ printDc(format, entry.getKey(), endpointsToTokens, entry.getValue(), showEffectiveOwnership);
- String load = loadMap.containsKey(endpoint)
- ? loadMap.get(endpoint)
- : "?";
- String owns = stat.owns != null && showEffectiveOwnership? new DecimalFormat("##0.00%").format(stat.owns) : "?";
- out.printf(format, stat.ipOrDns(), rack, status, state, load, owns, stat.token);
+ if (haveVnodes)
+ {
+ out.println(" Warning: \"nodetool ring\" is used to output all the tokens of a node.");
+ out.println(" To view status related info of a node use \"nodetool status\" instead.\n");
}
- out.println();
+
+ out.printf("%n " + errors.toString());
}
- private void printDc(NodeProbe probe, String format,
- String dc,
+ private void printDc(String format, String dc,
LinkedHashMultimap<String, String> endpointsToTokens,
- SetHostStatWithPort hoststats,boolean showEffectiveOwnership)
+ SetHostStatWithPort hoststats, boolean showEffectiveOwnership)
{
- PrintStream out = probe.output().out;
- Collection<String> liveNodes = probe.getLiveNodes(true);
- Collection<String> deadNodes = probe.getUnreachableNodes(true);
- Collection<String> joiningNodes = probe.getJoiningNodes(true);
- Collection<String> leavingNodes = probe.getLeavingNodes(true);
- Collection<String> movingNodes = probe.getMovingNodes(true);
- Map<String, String> loadMap = probe.getLoadMap(true);
-
out.println("Datacenter: " + dc);
out.println("==========");
@@ -244,9 +128,7 @@ public class Ring extends NodeToolCmd
for (HostStatWithPort stat : hoststats)
{
- // Remove extra '/' from address
- String addressNPort = stat.endpointWithPort.toString().replaceAll("^/", "");
- tokens.addAll(endpointsToTokens.get(addressNPort));
+ tokens.addAll(endpointsToTokens.get(stat.endpointWithPort.getHostAddressAndPort()));
lastToken = tokens.get(tokens.size() - 1);
}
@@ -259,11 +141,11 @@ public class Ring extends NodeToolCmd
for (HostStatWithPort stat : hoststats)
{
- String endpoint = stat.endpoint.toString();
+ String endpoint = stat.endpointWithPort.getHostAddressAndPort();
String rack;
try
{
- rack = probe.getEndpointSnitchInfoProxy().getRack(endpoint);
+ rack = epSnitchInfo.getRack(endpoint);
}
catch (UnknownHostException e)
{
@@ -289,7 +171,7 @@ public class Ring extends NodeToolCmd
? loadMap.get(endpoint)
: "?";
String owns = stat.owns != null && showEffectiveOwnership? new DecimalFormat("##0.00%").format(stat.owns) : "?";
- out.printf(format, stat.ipOrDns(), rack, status, state, load, owns, stat.token);
+ out.printf(format, stat.ipOrDns(printPort), rack, status, state, load, owns, stat.token);
}
out.println();
}
diff --git a/src/java/org/apache/cassandra/tools/nodetool/SetHostStatWithPort.java b/src/java/org/apache/cassandra/tools/nodetool/SetHostStatWithPort.java
index 6ac0258..d2abe6e 100644
--- a/src/java/org/apache/cassandra/tools/nodetool/SetHostStatWithPort.java
+++ b/src/java/org/apache/cassandra/tools/nodetool/SetHostStatWithPort.java
@@ -50,7 +50,7 @@ public class SetHostStatWithPort implements Iterable<HostStatWithPort>
public void add(String token, String host, Map<String, Float> ownerships) throws UnknownHostException
{
InetAddressAndPort endpoint = InetAddressAndPort.getByName(host);
- Float owns = ownerships.get(endpoint.toString());
+ Float owns = ownerships.get(endpoint.getHostAddressAndPort());
hostStats.add(new HostStatWithPort(token, endpoint, resolveIp, owns));
}
}
diff --git a/src/java/org/apache/cassandra/tools/nodetool/Status.java b/src/java/org/apache/cassandra/tools/nodetool/Status.java
index 4184939..369affc 100644
--- a/src/java/org/apache/cassandra/tools/nodetool/Status.java
+++ b/src/java/org/apache/cassandra/tools/nodetool/Status.java
@@ -57,14 +57,14 @@ public class Status extends NodeToolCmd
public void execute(NodeProbe probe)
{
PrintStream out = probe.output().out;
- joiningNodes = probe.getJoiningNodes(printPort);
- leavingNodes = probe.getLeavingNodes(printPort);
- movingNodes = probe.getMovingNodes(printPort);
- loadMap = probe.getLoadMap(printPort);
- Map<String, String> tokensToEndpoints = probe.getTokenToEndpointMap(printPort);
- liveNodes = probe.getLiveNodes(printPort);
- unreachableNodes = probe.getUnreachableNodes(printPort);
- hostIDMap = probe.getHostIdMap(printPort);
+ joiningNodes = probe.getJoiningNodes(true);
+ leavingNodes = probe.getLeavingNodes(true);
+ movingNodes = probe.getMovingNodes(true);
+ loadMap = probe.getLoadMap(true);
+ Map<String, String> tokensToEndpoints = probe.getTokenToEndpointMap(true);
+ liveNodes = probe.getLiveNodes(true);
+ unreachableNodes = probe.getUnreachableNodes(true);
+ hostIDMap = probe.getHostIdMap(true);
epSnitchInfo = probe.getEndpointSnitchInfoProxy();
StringBuilder errors = new StringBuilder();
@@ -102,14 +102,13 @@ public class Status extends NodeToolCmd
ArrayListMultimap<String, HostStatWithPort> hostToTokens = ArrayListMultimap.create();
for (HostStatWithPort stat : dc.getValue())
- hostToTokens.put(stat.ipOrDns(printPort), stat);
+ hostToTokens.put(stat.endpointWithPort.getHostAddressAndPort(), stat);
for (String endpoint : hostToTokens.keySet())
{
Float owns = ownerships.get(endpoint);
List<HostStatWithPort> tokens = hostToTokens.get(endpoint);
- addNode(endpoint, owns, tokens.get(0).ipOrDns(printPort), tokens.get(0).token, tokens.size(),
- hasEffectiveOwns, tableBuilder);
+ addNode(endpoint, owns, tokens.get(0), tokens.size(), hasEffectiveOwns, tableBuilder);
}
}
@@ -146,10 +145,10 @@ public class Status extends NodeToolCmd
tableBuilder.add("--", "Address", "Load", "Tokens", owns, "Host ID", "Rack");
}
- private void addNode(String endpoint, Float owns, String epDns, String token, int size, boolean hasEffectiveOwns,
+ private void addNode(String endpoint, Float owns, HostStatWithPort hostStat, int size, boolean hasEffectiveOwns,
TableBuilder tableBuilder)
{
- String status, state, load, strOwns, hostID, rack;
+ String status, state, load, strOwns, hostID, rack, epDns;
if (liveNodes.contains(endpoint)) status = "U";
else if (unreachableNodes.contains(endpoint)) status = "D";
else status = "?";
@@ -166,14 +165,16 @@ public class Status extends NodeToolCmd
try
{
rack = epSnitchInfo.getRack(endpoint);
- } catch (UnknownHostException e)
+ }
+ catch (UnknownHostException e)
{
throw new RuntimeException(e);
}
+ epDns = hostStat.ipOrDns(printPort);
if (isTokenPerNode)
{
- tableBuilder.add(statusAndState, epDns, load, strOwns, hostID, token, rack);
+ tableBuilder.add(statusAndState, epDns, load, strOwns, hostID, hostStat.token, rack);
}
else
{
diff --git a/test/distributed/org/apache/cassandra/distributed/test/NodeToolTest.java b/test/distributed/org/apache/cassandra/distributed/test/NodeToolTest.java
index 3e7f012..7c76080 100644
--- a/test/distributed/org/apache/cassandra/distributed/test/NodeToolTest.java
+++ b/test/distributed/org/apache/cassandra/distributed/test/NodeToolTest.java
@@ -52,7 +52,7 @@ public class NodeToolTest extends TestBaseImpl
}
@Test
- public void testCommands() throws Throwable
+ public void testCommands()
{
assertEquals(0, NODE.nodetool("help"));
assertEquals(0, NODE.nodetool("flush"));
@@ -60,11 +60,11 @@ public class NodeToolTest extends TestBaseImpl
}
@Test
- public void testCaptureConsoleOutput() throws Throwable
+ public void testCaptureConsoleOutput()
{
NodeToolResult ringResult = NODE.nodetoolResult("ring");
ringResult.asserts().stdoutContains("Datacenter: datacenter0");
- ringResult.asserts().stdoutContains("127.0.0.1 rack0 Up Normal");
+ ringResult.asserts().stdoutContains("127.0.0.1 rack0 Up Normal");
assertEquals("Non-empty error output", "", ringResult.getStderr());
}
diff --git a/test/distributed/org/apache/cassandra/distributed/test/NodeToolRingTest.java b/test/unit/org/apache/cassandra/tools/nodetool/RingTest.java
similarity index 58%
rename from test/distributed/org/apache/cassandra/distributed/test/NodeToolRingTest.java
rename to test/unit/org/apache/cassandra/tools/nodetool/RingTest.java
index 74f4275..83771f6 100644
--- a/test/distributed/org/apache/cassandra/distributed/test/NodeToolRingTest.java
+++ b/test/unit/org/apache/cassandra/tools/nodetool/RingTest.java
@@ -16,44 +16,96 @@
* limitations under the License.
*/
-package org.apache.cassandra.distributed.test;
+package org.apache.cassandra.tools.nodetool;
-import java.io.IOException;
import java.util.Arrays;
-import org.junit.AfterClass;
-import org.junit.Before;
+import org.junit.BeforeClass;
import org.junit.Test;
+import org.junit.runner.RunWith;
-import org.apache.cassandra.distributed.api.ICluster;
+import org.apache.cassandra.OrderedJUnit4ClassRunner;
+import org.apache.cassandra.cql3.CQLTester;
+import org.apache.cassandra.locator.SimpleSnitch;
+import org.apache.cassandra.service.StorageService;
import org.apache.cassandra.tools.ToolRunner;
-import org.apache.cassandra.tools.ToolRunner.ToolResult;
+import org.apache.cassandra.utils.FBUtilities;
import org.assertj.core.api.Assertions;
+import static org.hamcrest.CoreMatchers.*;
+import static org.hamcrest.Matchers.matchesPattern;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
-public class NodeToolRingTest extends TestBaseImpl
+@RunWith(OrderedJUnit4ClassRunner.class)
+public class RingTest extends CQLTester
{
- private static ICluster cluster;
+ private static String token;
- @Before
- public void setupEnv() throws IOException
+ @BeforeClass
+ public static void setup() throws Exception
{
- if (cluster == null)
- cluster = init(builder().withNodes(1).start());
+ StorageService.instance.initServer();
+ token = StorageService.instance.getTokens().get(0);
+ startJMXServer();
}
- @AfterClass
- public static void teardownEnv() throws Exception
+ /**
+ * Validate output, making sure the table mappings work with various host-modifying arguments in use.
+ */
+ @Test
+ public void testRingOutput()
+ {
+ final HostStatWithPort host = new HostStatWithPort(null, FBUtilities.getBroadcastAddressAndPort(),
+ false, null);
+ validateRingOutput(host.ipOrDns(false),
+ "ring");
+ Arrays.asList("-pp", "--print-port").forEach(arg -> {
+ validateRingOutput(host.ipOrDns(true),
+ "-pp", "ring");
+ });
+
+ final HostStatWithPort hostResolved = new HostStatWithPort(null, FBUtilities.getBroadcastAddressAndPort(),
+ true, null);
+ Arrays.asList("-r", "--resolve-ip").forEach(arg -> {
+ validateRingOutput(hostResolved.ipOrDns(false),
+ "ring", "-r");
+ });
+ validateRingOutput(hostResolved.ipOrDns(true),
+ "-pp", "ring", "-r");
+ }
+
+ private void validateRingOutput(String hostForm, String... args)
{
- cluster.close();
+ ToolRunner.ToolResult nodetool = ToolRunner.invokeNodetool(args);
+ nodetool.assertOnCleanExit();
+ /*
+ Datacenter: datacenter1
+ ==========
+ Address Rack Status State Load Owns Token
+
+ 127.0.0.1 rack1 Up Normal 45.71 KiB 100.00% 4652409154190094022
+
+ */
+ String[] lines = nodetool.getStdout().split("\\R");
+ assertThat(lines[1].trim(), endsWith(SimpleSnitch.DATA_CENTER_NAME));
+ assertThat(lines[3], matchesPattern("Address *Rack *Status *State *Load *Owns *Token *"));
+ String hostRing = lines[lines.length-4].trim(); // this command has a couple extra newlines and an empty error message at the end. Not messing with it.
+ assertThat(hostRing, startsWith(hostForm));
+ assertThat(hostRing, containsString(SimpleSnitch.RACK_NAME));
+ assertThat(hostRing, containsString("Up"));
+ assertThat(hostRing, containsString("Normal"));
+ assertThat(hostRing, matchesPattern(".*\\d+\\.\\d+ KiB.*"));
+ assertThat(hostRing, matchesPattern(".*\\d+\\.\\d+%.*"));
+ assertThat(hostRing, endsWith(token));
+ assertThat(hostRing, not(containsString("?")));
}
@Test
public void testWrongArgFailsAndPrintsHelp()
{
- ToolResult tool = ToolRunner.invokeNodetoolJvmDtest(cluster.get(1), "--wrongarg", "ring");
+ ToolRunner.ToolResult tool = ToolRunner.invokeNodetool("--wrongarg", "ring");
Assertions.assertThat(tool.getStdout()).containsIgnoringCase("nodetool help");
assertEquals(1, tool.getExitCode());
assertTrue(tool.getCleanedStderr().isEmpty());
@@ -64,8 +116,8 @@ public class NodeToolRingTest extends TestBaseImpl
{
// If you added, modified options or help, please update docs if necessary
- ToolResult tool = ToolRunner.invokeNodetoolJvmDtest(cluster.get(1), "help", "ring");
-
+ ToolRunner.ToolResult tool = ToolRunner.invokeNodetool("help", "ring");
+
String help = "NAME\n" + " nodetool ring - Print information about the token ring\n"
+ "\n"
+ "SYNOPSIS\n"
@@ -111,62 +163,17 @@ public class NodeToolRingTest extends TestBaseImpl
}
@Test
- public void testRing()
- {
- ToolResult tool = ToolRunner.invokeNodetoolJvmDtest(cluster.get(1), "ring");
-
- Assertions.assertThat(tool.getStdout())
- .contains("Datacenter: datacenter0")
- .contains("Address Rack Status State Load Owns Token")
- .contains("127.0.0.1 rack0 Up Normal")
- .contains("100.00% 9223372036854775807");
- assertEquals(0, tool.getExitCode());
- assertTrue(tool.getCleanedStderr().isEmpty());
- }
-
- @Test
- public void testRingPrintPort()
- {
- Arrays.asList("-pp", "--print-port").forEach(arg -> {
- ToolResult tool = ToolRunner.invokeNodetoolJvmDtest(cluster.get(1), arg, "ring");
- Assertions.assertThat(tool.getStdout())
- .contains("Datacenter: datacenter0")
- .contains("Address Rack Status State Load Owns Token")
- .contains("Unknown")
- .contains("100.00% 9223372036854775807");
- assertEquals(0, tool.getExitCode());
- assertTrue(tool.getCleanedStderr().isEmpty());
- });
- }
-
- @Test
- public void testRingResolve()
- {
- Arrays.asList("-r", "--resolve-ip").forEach(arg -> {
- ToolResult tool = ToolRunner.invokeNodetoolJvmDtest(cluster.get(1), "ring", arg);
- Assertions.assertThat(tool.getStdout())
- .contains("Datacenter: datacenter0")
- .contains("Address Rack Status State Load Owns Token")
- .contains("localhost")
- .contains("rack0 Up Normal")
- .contains("100.00% 9223372036854775807");
- assertEquals(0, tool.getExitCode());
- assertTrue(tool.getCleanedStderr().isEmpty());
- });
- }
-
- @Test
public void testRingKeyspace()
{
// Bad KS
- ToolResult tool = ToolRunner.invokeNodetoolJvmDtest(cluster.get(1), "ring", "mockks");
+ ToolRunner.ToolResult tool = ToolRunner.invokeNodetool("ring", "mockks");
Assertions.assertThat(tool.getStdout()).contains("The keyspace mockks, does not exist");
assertEquals(0, tool.getExitCode());
assertTrue(tool.getCleanedStderr().isEmpty());
// Good KS
- tool = ToolRunner.invokeNodetoolJvmDtest(cluster.get(1), "ring", "system_schema");
- Assertions.assertThat(tool.getStdout()).contains("Datacenter: datacenter0");
+ tool = ToolRunner.invokeNodetool("ring", "system_schema");
+ Assertions.assertThat(tool.getStdout()).contains("Datacenter: datacenter1");
assertEquals(0, tool.getExitCode());
assertTrue(tool.getCleanedStderr().isEmpty());
}
diff --git a/test/unit/org/apache/cassandra/tools/nodetool/StatusTest.java b/test/unit/org/apache/cassandra/tools/nodetool/StatusTest.java
new file mode 100644
index 0000000..a7f939c
--- /dev/null
+++ b/test/unit/org/apache/cassandra/tools/nodetool/StatusTest.java
@@ -0,0 +1,93 @@
+/*
+ * 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.nodetool;
+
+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.locator.SimpleSnitch;
+import org.apache.cassandra.service.StorageService;
+import org.apache.cassandra.tools.ToolRunner;
+import org.apache.cassandra.utils.FBUtilities;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.hamcrest.Matchers.matchesPattern;
+import static org.junit.Assert.assertThat;
+
+@RunWith(OrderedJUnit4ClassRunner.class)
+public class StatusTest extends CQLTester
+{
+ private static String localHostId;
+ private static String token;
+
+ @BeforeClass
+ public static void setup() throws Exception
+ {
+ StorageService.instance.initServer();
+ localHostId = StorageService.instance.getLocalHostId();
+ token = StorageService.instance.getTokens().get(0);
+ startJMXServer();
+ }
+
+ /**
+ * Validate output, making sure the table mappings work with various host-modifying arguments in use.
+ */
+ @Test
+ public void testStatusOutput()
+ {
+ HostStatWithPort host = new HostStatWithPort(null, FBUtilities.getBroadcastAddressAndPort(), false, null);
+ validateStatusOutput(host.ipOrDns(false),
+ "status");
+ validateStatusOutput(host.ipOrDns(true),
+ "-pp", "status");
+ host = new HostStatWithPort(null, FBUtilities.getBroadcastAddressAndPort(), true, null);
+ validateStatusOutput(host.ipOrDns(false),
+ "status", "-r");
+ validateStatusOutput(host.ipOrDns(true),
+ "-pp", "status", "-r");
+ }
+
+ private void validateStatusOutput(String hostForm, String... args)
+ {
+ ToolRunner.ToolResult nodetool = ToolRunner.invokeNodetool(args);
+ nodetool.assertOnCleanExit();
+ /*
+ Datacenter: datacenter1
+ =======================
+ Status=Up/Down
+ |/ State=Normal/Leaving/Joining/Moving
+ -- Address Load Owns (effective) Host ID Token Rack
+ UN localhost 45.71 KiB 100.0% 0b1b5e91-ad3b-444e-9c24-50578486978a 1849950853373272258 rack1
+ */
+ String[] lines = nodetool.getStdout().split("\\R");
+ assertThat(lines[0].trim(), endsWith(SimpleSnitch.DATA_CENTER_NAME));
+ String hostStatus = lines[lines.length-1].trim();
+ assertThat(hostStatus, startsWith("UN"));
+ assertThat(hostStatus, containsString(hostForm));
+ assertThat(hostStatus, matchesPattern(".*\\d+\\.\\d+ KiB.*"));
+ assertThat(hostStatus, matchesPattern(".*\\d+\\.\\d+%.*"));
+ assertThat(hostStatus, containsString(localHostId));
+ assertThat(hostStatus, containsString(token));
+ assertThat(hostStatus, endsWith(SimpleSnitch.RACK_NAME));
+ assertThat(hostStatus, not(containsString("?")));
+ }
+}
diff --git a/test/unit/org/apache/cassandra/tools/nodetool/stats/NodetoolTableStatsTest.java b/test/unit/org/apache/cassandra/tools/nodetool/stats/NodetoolTableStatsTest.java
index 8edf2e0..528a6ca 100644
--- a/test/unit/org/apache/cassandra/tools/nodetool/stats/NodetoolTableStatsTest.java
+++ b/test/unit/org/apache/cassandra/tools/nodetool/stats/NodetoolTableStatsTest.java
@@ -18,7 +18,6 @@
package org.apache.cassandra.tools.nodetool.stats;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -27,7 +26,6 @@ import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils;
-import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -35,7 +33,6 @@ import org.junit.runner.RunWith;
import org.apache.cassandra.OrderedJUnit4ClassRunner;
import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.service.StorageService;
-import org.apache.cassandra.tools.NodeProbe;
import org.apache.cassandra.tools.ToolRunner;
import org.apache.cassandra.tools.ToolRunner.ToolResult;
import org.assertj.core.api.Assertions;
@@ -49,20 +46,11 @@ import static org.junit.Assert.assertTrue;
@RunWith(OrderedJUnit4ClassRunner.class)
public class NodetoolTableStatsTest extends CQLTester
{
- private static NodeProbe probe;
-
@BeforeClass
public static void setup() throws Exception
{
StorageService.instance.initServer();
startJMXServer();
- probe = new NodeProbe(jmxHost, jmxPort);
- }
-
- @AfterClass
- public static void teardown() throws IOException
- {
- probe.close();
}
@Test
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cassandra.apache.org
For additional commands, e-mail: commits-help@cassandra.apache.org