You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by ma...@apache.org on 2021/09/20 12:25:50 UTC

[cassandra] branch trunk updated (e603418 -> b085591)

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

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


    from e603418  Merge branch 'cassandra-4.0' into trunk
     new 9e9dffb  Remove OrderedJUnit4ClassRunner
     new b085591  Merge branch 'cassandra-4.0' into trunk

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 ide/idea/workspace.xml                             |   1 +
 .../db/compaction/CompactionAllocationTest.java    |   3 -
 .../apache/cassandra/OrderedJUnit4ClassRunner.java |  55 -----
 .../cassandra/audit/AuditLoggerAuthTest.java       |   4 +-
 .../cassandra/config/DatabaseDescriptorTest.java   |   3 -
 .../cql3/validation/operations/AlterNTSTest.java   | 103 +++++++++
 .../cql3/validation/operations/AlterTest.java      |  77 -------
 .../cql3/validation/operations/TTLTest.java        |  12 +-
 .../apache/cassandra/db/ColumnFamilyStoreTest.java |   4 +-
 test/unit/org/apache/cassandra/db/ScrubTest.java   | 238 ++++----------------
 .../org/apache/cassandra/db/ScrubToolTest.java     | 249 +++++++++++++++++++++
 test/unit/org/apache/cassandra/db/VerifyTest.java  |   6 -
 .../cassandra/db/compaction/CompactionsTest.java   |   4 -
 .../compaction/LeveledCompactionStrategyTest.java  |   3 -
 .../cassandra/db/compaction/TTLExpiryTest.java     |   3 -
 .../org/apache/cassandra/dht/BootStrapperTest.java |   3 -
 .../cassandra/diag/DiagnosticEventServiceTest.java |   5 +-
 .../io/sstable/IndexSummaryManagerTest.java        |   6 -
 .../cassandra/io/sstable/LargePartitionsTest.java  |   3 -
 .../cassandra/locator/TokenMetadataTest.java       |   3 -
 .../apache/cassandra/metrics/BatchMetricsTest.java |   3 -
 .../cassandra/metrics/BufferPoolMetricsTest.java   |   3 -
 .../apache/cassandra/metrics/CQLMetricsTest.java   |   3 -
 .../apache/cassandra/metrics/CacheMetricsTest.java |   3 -
 .../apache/cassandra/metrics/TableMetricsTest.java |   5 +-
 .../schema/MigrationManagerDropKSTest.java         | 106 +++++++++
 .../cassandra/schema/MigrationManagerTest.java     |  53 -----
 .../apache/cassandra/service/GCInspectorTest.java  |   3 -
 .../apache/cassandra/service/QueryPagerTest.java   |   3 -
 .../service/StorageServiceServerM3PTest.java       |  68 ++++++
 .../service/StorageServiceServerTest.java          |  25 +--
 .../cassandra/streaming/StreamingTransferTest.java |   4 +-
 .../org/apache/cassandra/tools/BulkLoaderTest.java |   6 +-
 .../cassandra/tools/CompactionStressTest.java      |   3 -
 .../org/apache/cassandra/tools/GetVersionTest.java |   3 -
 .../apache/cassandra/tools/OfflineToolUtils.java   |   1 +
 .../tools/SSTableExpiredBlockersTest.java          |   3 -
 .../apache/cassandra/tools/SSTableExportTest.java  |   4 -
 .../cassandra/tools/SSTableLevelResetterTest.java  |   3 -
 .../cassandra/tools/SSTableMetadataViewerTest.java |   3 -
 .../cassandra/tools/SSTableOfflineRelevelTest.java |   3 -
 .../tools/SSTableRepairedAtSetterTest.java         |   4 -
 .../cassandra/tools/StandaloneSSTableUtilTest.java |  18 --
 .../cassandra/tools/StandaloneScrubberTest.java    |  18 --
 .../cassandra/tools/StandaloneSplitterTest.java    |  18 --
 .../tools/StandaloneSplitterWithCQLTesterTest.java |  70 +-----
 .../tools/StandaloneUpgraderOnSStablesTest.java    |   8 +-
 .../cassandra/tools/StandaloneUpgraderTest.java    |  18 --
 .../cassandra/tools/StandaloneVerifierTest.java    |  19 --
 .../cassandra/tools/ToolsSchemaLoadingTest.java    | 104 +++++++++
 .../tools/nodetool/ClearSnapshotTest.java          |   3 -
 .../cassandra/tools/nodetool/GetAuditLogTest.java  |   3 -
 .../tools/nodetool/GetFullQueryLogTest.java        |   3 -
 .../cassandra/tools/nodetool/GossipInfoTest.java   |   3 -
 .../nodetool/InvalidateCredentialsCacheTest.java   |   3 -
 .../InvalidateJmxPermissionsCacheTest.java         |   3 -
 .../InvalidateNetworkPermissionsCacheTest.java     |   3 -
 .../nodetool/InvalidatePermissionsCacheTest.java   |   3 -
 .../tools/nodetool/InvalidateRolesCacheTest.java   |   3 -
 .../cassandra/tools/nodetool/NetStatsTest.java     |   3 -
 .../apache/cassandra/tools/nodetool/RingTest.java  |   3 -
 .../cassandra/tools/nodetool/StatusTest.java       |   3 -
 .../cassandra/tools/nodetool/TableStatsTest.java   |   3 -
 .../cassandra/tools/nodetool/TpStatsTest.java      |   3 -
 .../cassandra/transport/CQLUserAuditTest.java      |   3 -
 65 files changed, 693 insertions(+), 722 deletions(-)
 delete mode 100644 test/unit/org/apache/cassandra/OrderedJUnit4ClassRunner.java
 create mode 100644 test/unit/org/apache/cassandra/cql3/validation/operations/AlterNTSTest.java
 create mode 100644 test/unit/org/apache/cassandra/db/ScrubToolTest.java
 create mode 100644 test/unit/org/apache/cassandra/schema/MigrationManagerDropKSTest.java
 create mode 100644 test/unit/org/apache/cassandra/service/StorageServiceServerM3PTest.java
 create mode 100644 test/unit/org/apache/cassandra/tools/ToolsSchemaLoadingTest.java

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cassandra.apache.org
For additional commands, e-mail: commits-help@cassandra.apache.org


[cassandra] 01/01: Merge branch 'cassandra-4.0' into trunk

Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit b0855914ef673b183efec0dd132847ddb9d96f5f
Merge: e603418 9e9dffb
Author: Marcus Eriksson <ma...@apache.org>
AuthorDate: Mon Sep 20 13:38:05 2021 +0200

    Merge branch 'cassandra-4.0' into trunk

 ide/idea/workspace.xml                             |   1 +
 .../db/compaction/CompactionAllocationTest.java    |   3 -
 .../apache/cassandra/OrderedJUnit4ClassRunner.java |  55 -----
 .../cassandra/audit/AuditLoggerAuthTest.java       |   4 +-
 .../cassandra/config/DatabaseDescriptorTest.java   |   3 -
 .../cql3/validation/operations/AlterNTSTest.java   | 103 +++++++++
 .../cql3/validation/operations/AlterTest.java      |  77 -------
 .../cql3/validation/operations/TTLTest.java        |  12 +-
 .../apache/cassandra/db/ColumnFamilyStoreTest.java |   4 +-
 test/unit/org/apache/cassandra/db/ScrubTest.java   | 238 ++++----------------
 .../org/apache/cassandra/db/ScrubToolTest.java     | 249 +++++++++++++++++++++
 test/unit/org/apache/cassandra/db/VerifyTest.java  |   6 -
 .../cassandra/db/compaction/CompactionsTest.java   |   4 -
 .../compaction/LeveledCompactionStrategyTest.java  |   3 -
 .../cassandra/db/compaction/TTLExpiryTest.java     |   3 -
 .../org/apache/cassandra/dht/BootStrapperTest.java |   3 -
 .../cassandra/diag/DiagnosticEventServiceTest.java |   5 +-
 .../io/sstable/IndexSummaryManagerTest.java        |   6 -
 .../cassandra/io/sstable/LargePartitionsTest.java  |   3 -
 .../cassandra/locator/TokenMetadataTest.java       |   3 -
 .../apache/cassandra/metrics/BatchMetricsTest.java |   3 -
 .../cassandra/metrics/BufferPoolMetricsTest.java   |   3 -
 .../apache/cassandra/metrics/CQLMetricsTest.java   |   3 -
 .../apache/cassandra/metrics/CacheMetricsTest.java |   3 -
 .../apache/cassandra/metrics/TableMetricsTest.java |   5 +-
 .../schema/MigrationManagerDropKSTest.java         | 106 +++++++++
 .../cassandra/schema/MigrationManagerTest.java     |  53 -----
 .../apache/cassandra/service/GCInspectorTest.java  |   3 -
 .../apache/cassandra/service/QueryPagerTest.java   |   3 -
 .../service/StorageServiceServerM3PTest.java       |  68 ++++++
 .../service/StorageServiceServerTest.java          |  25 +--
 .../cassandra/streaming/StreamingTransferTest.java |   4 +-
 .../org/apache/cassandra/tools/BulkLoaderTest.java |   6 +-
 .../cassandra/tools/CompactionStressTest.java      |   3 -
 .../org/apache/cassandra/tools/GetVersionTest.java |   3 -
 .../apache/cassandra/tools/OfflineToolUtils.java   |   1 +
 .../tools/SSTableExpiredBlockersTest.java          |   3 -
 .../apache/cassandra/tools/SSTableExportTest.java  |   4 -
 .../cassandra/tools/SSTableLevelResetterTest.java  |   3 -
 .../cassandra/tools/SSTableMetadataViewerTest.java |   3 -
 .../cassandra/tools/SSTableOfflineRelevelTest.java |   3 -
 .../tools/SSTableRepairedAtSetterTest.java         |   4 -
 .../cassandra/tools/StandaloneSSTableUtilTest.java |  18 --
 .../cassandra/tools/StandaloneScrubberTest.java    |  18 --
 .../cassandra/tools/StandaloneSplitterTest.java    |  18 --
 .../tools/StandaloneSplitterWithCQLTesterTest.java |  70 +-----
 .../tools/StandaloneUpgraderOnSStablesTest.java    |   8 +-
 .../cassandra/tools/StandaloneUpgraderTest.java    |  18 --
 .../cassandra/tools/StandaloneVerifierTest.java    |  19 --
 .../cassandra/tools/ToolsSchemaLoadingTest.java    | 104 +++++++++
 .../tools/nodetool/ClearSnapshotTest.java          |   3 -
 .../cassandra/tools/nodetool/GetAuditLogTest.java  |   3 -
 .../tools/nodetool/GetFullQueryLogTest.java        |   3 -
 .../cassandra/tools/nodetool/GossipInfoTest.java   |   3 -
 .../nodetool/InvalidateCredentialsCacheTest.java   |   3 -
 .../InvalidateJmxPermissionsCacheTest.java         |   3 -
 .../InvalidateNetworkPermissionsCacheTest.java     |   3 -
 .../nodetool/InvalidatePermissionsCacheTest.java   |   3 -
 .../tools/nodetool/InvalidateRolesCacheTest.java   |   3 -
 .../cassandra/tools/nodetool/NetStatsTest.java     |   3 -
 .../apache/cassandra/tools/nodetool/RingTest.java  |   3 -
 .../cassandra/tools/nodetool/StatusTest.java       |   3 -
 .../cassandra/tools/nodetool/TableStatsTest.java   |   3 -
 .../cassandra/tools/nodetool/TpStatsTest.java      |   3 -
 .../cassandra/transport/CQLUserAuditTest.java      |   3 -
 65 files changed, 693 insertions(+), 722 deletions(-)

diff --cc test/memory/org/apache/cassandra/db/compaction/CompactionAllocationTest.java
index 8c8b706,4398b3d..976872f
--- a/test/memory/org/apache/cassandra/db/compaction/CompactionAllocationTest.java
+++ b/test/memory/org/apache/cassandra/db/compaction/CompactionAllocationTest.java
@@@ -76,9 -64,7 +74,8 @@@ import org.apache.cassandra.service.Cli
  import org.apache.cassandra.service.QueryState;
  import org.apache.cassandra.utils.FBUtilities;
  import org.apache.cassandra.utils.ObjectSizes;
 +import org.apache.cassandra.utils.concurrent.Refs;
  
- @RunWith(OrderedJUnit4ClassRunner.class)
  public class CompactionAllocationTest
  {
      private static final Logger logger = LoggerFactory.getLogger(CompactionAllocationTest.class);
diff --cc test/unit/org/apache/cassandra/db/ColumnFamilyStoreTest.java
index 583c1eb,df88374..c22f963
--- a/test/unit/org/apache/cassandra/db/ColumnFamilyStoreTest.java
+++ b/test/unit/org/apache/cassandra/db/ColumnFamilyStoreTest.java
@@@ -30,16 -31,12 +30,15 @@@ import org.junit.Before
  import org.junit.Assume;
  import org.junit.BeforeClass;
  import org.junit.Test;
- import org.junit.runner.RunWith;
  
 -import org.json.simple.JSONArray;
 -import org.json.simple.JSONObject;
 -import org.json.simple.parser.JSONParser;
 +import org.apache.cassandra.io.util.FileUtils;
 +import org.apache.cassandra.schema.SchemaConstants;
 +import org.apache.cassandra.service.snapshot.SnapshotManifest;
 +import org.apache.cassandra.service.snapshot.TableSnapshot;
  
 +import static org.assertj.core.api.Assertions.assertThat;
  import static org.junit.Assert.assertEquals;
 +import static org.junit.Assert.assertFalse;
  import static org.junit.Assert.assertTrue;
  
  import com.google.common.collect.Iterators;
diff --cc test/unit/org/apache/cassandra/tools/nodetool/ClearSnapshotTest.java
index 07a89d7,975e45b..2bbcf06
--- a/test/unit/org/apache/cassandra/tools/nodetool/ClearSnapshotTest.java
+++ b/test/unit/org/apache/cassandra/tools/nodetool/ClearSnapshotTest.java
@@@ -23,18 -23,19 +23,15 @@@ import java.util.Map
  import javax.management.openmbean.TabularData;
  
  import org.junit.AfterClass;
 -import org.junit.Assert;
  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.tools.ToolRunner.ToolResult;
 -import org.hamcrest.CoreMatchers;
 +import org.apache.cassandra.tools.NodeProbe;
 +import org.apache.cassandra.tools.ToolRunner;
  
 -import static org.junit.Assert.assertEquals;
 -import static org.junit.Assert.assertThat;
 -import static org.junit.Assert.assertTrue;
 +import static org.assertj.core.api.Assertions.assertThat;
  
- @RunWith(OrderedJUnit4ClassRunner.class)
  public class ClearSnapshotTest extends CQLTester
  {
      private static NodeProbe probe;
diff --cc test/unit/org/apache/cassandra/tools/nodetool/GetAuditLogTest.java
index d0eda31,0000000..069710b
mode 100644,000000..100644
--- a/test/unit/org/apache/cassandra/tools/nodetool/GetAuditLogTest.java
+++ b/test/unit/org/apache/cassandra/tools/nodetool/GetAuditLogTest.java
@@@ -1,155 -1,0 +1,152 @@@
 +/*
 + * 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.After;
 +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.tools.ToolRunner;
 +
 +import static org.assertj.core.api.Assertions.assertThat;
 +
- @RunWith(OrderedJUnit4ClassRunner.class)
 +public class GetAuditLogTest extends CQLTester
 +{
 +    @BeforeClass
 +    public static void setup() throws Exception
 +    {
 +        startJMXServer();
 +    }
 +
 +    @After
 +    public void afterTest()
 +    {
 +        disableAuditLog();
 +    }
 +
 +    @Test
 +    public void getDefaultOutputTest()
 +    {
 +        testDefaultOutput(getAuditLog());
 +    }
 +
 +    @Test
 +    public void getSimpleOutputTest()
 +    {
 +        enableAuditLogSimple();
 +        testChangedOutputSimple(getAuditLog());
 +    }
 +
 +    @Test
 +    public void getComplexOutputTest()
 +    {
 +        enableAuditLogComplex();
 +        testChangedOutputComplex(getAuditLog());
 +    }
 +
 +    @Test
 +    public void disablingAuditLogResetsOutputTest()
 +    {
 +        enableAuditLogComplex();
 +        disableAuditLog();
 +        testDefaultOutput(getAuditLog());
 +    }
 +
 +    private String getAuditLog()
 +    {
 +        ToolRunner.ToolResult tool = ToolRunner.invokeNodetool("getauditlog");
 +        tool.assertOnCleanExit();
 +        return tool.getStdout();
 +    }
 +
 +    private void disableAuditLog()
 +    {
 +        ToolRunner.invokeNodetool("disableauditlog").assertOnCleanExit();
 +    }
 +
 +    private void enableAuditLogSimple()
 +    {
 +        ToolRunner.invokeNodetool("enableauditlog").assertOnCleanExit();
 +    }
 +
 +    private void enableAuditLogComplex()
 +    {
 +        ToolRunner.invokeNodetool("enableauditlog",
 +                                  "--included-keyspaces", "ks1,ks2,ks3",
 +                                  "--excluded-categories", "ddl,dcl").assertOnCleanExit();
 +    }
 +
 +    @SuppressWarnings("DynamicRegexReplaceableByCompiledPattern")
 +    private void testChangedOutputSimple(final String getAuditLogOutput)
 +    {
 +        final String output = getAuditLogOutput.replaceAll("( )+", " ").trim();
 +        assertThat(output).startsWith("enabled true");
 +        assertThat(output).contains("logger BinAuditLogger");
 +        assertThat(output).contains("roll_cycle HOURLY");
 +        assertThat(output).contains("block true");
 +        assertThat(output).contains("max_log_size 17179869184");
 +        assertThat(output).contains("max_queue_weight 268435456");
 +        assertThat(output).contains("max_archive_retries 10");
 +        assertThat(output).contains("included_keyspaces \n");
 +        assertThat(output).contains("excluded_keyspaces system,system_schema,system_virtual_schema");
 +        assertThat(output).contains("included_categories \n");
 +        assertThat(output).contains("excluded_categories \n");
 +        assertThat(output).contains("included_users \n");
 +        assertThat(output).endsWith("excluded_users");
 +    }
 +
 +    @SuppressWarnings("DynamicRegexReplaceableByCompiledPattern")
 +    private void testChangedOutputComplex(final String getAuditLogOutput)
 +    {
 +        final String output = getAuditLogOutput.replaceAll("( )+", " ").trim();
 +        assertThat(output).startsWith("enabled true");
 +        assertThat(output).contains("logger BinAuditLogger");
 +        assertThat(output).contains("roll_cycle HOURLY");
 +        assertThat(output).contains("block true");
 +        assertThat(output).contains("max_log_size 17179869184");
 +        assertThat(output).contains("max_queue_weight 268435456");
 +        assertThat(output).contains("max_archive_retries 10");
 +        assertThat(output).contains("included_keyspaces ks1,ks2,ks3");
 +        assertThat(output).contains("excluded_keyspaces system,system_schema,system_virtual_schema");
 +        assertThat(output).contains("included_categories \n");
 +        assertThat(output).contains("excluded_categories DDL,DCL");
 +        assertThat(output).contains("included_users \n");
 +        assertThat(output).endsWith("excluded_users");
 +    }
 +
 +    @SuppressWarnings("DynamicRegexReplaceableByCompiledPattern")
 +    private void testDefaultOutput(final String getAuditLogOutput)
 +    {
 +        final String output = getAuditLogOutput.replaceAll("( )+", " ").trim();
 +        assertThat(output).startsWith("enabled false");
 +        assertThat(output).contains("logger BinAuditLogger");
 +        assertThat(output).contains("roll_cycle HOURLY");
 +        assertThat(output).contains("block true");
 +        assertThat(output).contains("max_log_size 17179869184");
 +        assertThat(output).contains("max_queue_weight 268435456");
 +        assertThat(output).contains("max_archive_retries 10");
 +        assertThat(output).contains("included_keyspaces \n");
 +        assertThat(output).contains("excluded_keyspaces system,system_schema,system_virtual_schema");
 +        assertThat(output).contains("included_categories \n");
 +        assertThat(output).contains("excluded_categories \n");
 +        assertThat(output).contains("included_users \n");
 +        assertThat(output).endsWith("excluded_users");
 +    }
 +}
diff --cc test/unit/org/apache/cassandra/tools/nodetool/GetFullQueryLogTest.java
index c4eb70c,44007a5..61d34ec
--- a/test/unit/org/apache/cassandra/tools/nodetool/GetFullQueryLogTest.java
+++ b/test/unit/org/apache/cassandra/tools/nodetool/GetFullQueryLogTest.java
@@@ -23,18 -26,18 +23,15 @@@ import org.junit.BeforeClass
  import org.junit.ClassRule;
  import org.junit.Test;
  import org.junit.rules.TemporaryFolder;
- import org.junit.runner.RunWith;
  
- import org.apache.cassandra.OrderedJUnit4ClassRunner;
  import org.apache.cassandra.cql3.CQLTester;
  import org.apache.cassandra.fql.FullQueryLoggerOptions;
 -import org.apache.cassandra.tools.ToolRunner.ToolResult;
 +import org.apache.cassandra.tools.ToolRunner;
  
 -import static org.junit.Assert.assertFalse;
 -import static org.junit.Assert.assertTrue;
 +import static org.assertj.core.api.Assertions.assertThat;
  
- @RunWith(OrderedJUnit4ClassRunner.class)
  public class GetFullQueryLogTest extends CQLTester
  {
 -    private static NodeProbe probe;
 -
      @ClassRule
      public static TemporaryFolder temporaryFolder = new TemporaryFolder();
  
diff --cc test/unit/org/apache/cassandra/tools/nodetool/GossipInfoTest.java
index 7a48db8,0000000..35801fd
mode 100644,000000..100644
--- a/test/unit/org/apache/cassandra/tools/nodetool/GossipInfoTest.java
+++ b/test/unit/org/apache/cassandra/tools/nodetool/GossipInfoTest.java
@@@ -1,124 -1,0 +1,121 @@@
 +/*
 + * 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.apache.commons.lang3.StringUtils;
 +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.service.StorageService;
 +import org.apache.cassandra.tools.ToolRunner;
 +import org.apache.cassandra.utils.FBUtilities;
 +import org.assertj.core.api.Assertions;
 +
 +import static org.apache.cassandra.net.Verb.ECHO_REQ;
 +import static org.assertj.core.api.Assertions.assertThat;
 +
- @RunWith(OrderedJUnit4ClassRunner.class)
 +public class GossipInfoTest extends CQLTester
 +{
 +    private static String token;
 +
 +    @BeforeClass
 +    public static void setup() throws Exception
 +    {
 +        requireNetwork();
 +        startJMXServer();
 +        token = StorageService.instance.getTokens().get(0);
 +    }
 +
 +    @Test
 +    @SuppressWarnings("SingleCharacterStringConcatenation")
 +    public void testMaybeChangeDocs()
 +    {
 +        // If you added, modified options or help, please update docs if necessary
 +        ToolRunner.ToolResult tool = ToolRunner.invokeNodetool("help", "gossipinfo");
 +        tool.assertOnCleanExit();
 +
 +        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";
 +        assertThat(tool.getStdout()).isEqualTo(help);
 +    }
 +
 +    @Test
 +    public void testGossipInfo()
 +    {
 +        ToolRunner.ToolResult tool = ToolRunner.invokeNodetool("gossipinfo");
 +        tool.assertOnCleanExit();
 +        String stdout = tool.getStdout();
 +        Assertions.assertThat(stdout).contains("/127.0.0.1");
 +        Assertions.assertThat(stdout).containsPattern("\\s+generation:[0-9]+");
 +        Assertions.assertThat(stdout).containsPattern("heartbeat:[0-9]+");
 +        Assertions.assertThat(stdout).containsPattern("STATUS:[0-9]+:NORMAL," + token);
 +        Assertions.assertThat(stdout).containsPattern("SCHEMA:.+");
 +        Assertions.assertThat(stdout).containsPattern("DC:[0-9]+:datacenter1");
 +        Assertions.assertThat(stdout).containsPattern("RACK:[0-9]+:rack1");
 +        Assertions.assertThat(stdout).containsPattern("RELEASE_VERSION:.+");
 +        Assertions.assertThat(stdout).containsPattern("RPC_ADDRESS:[0-9]+:127.0.0.1");
 +        Assertions.assertThat(stdout).containsPattern("NET_VERSION:[0-9]+:.+");
 +        Assertions.assertThat(stdout).containsPattern("HOST_ID:[0-9]+:.+");
 +        Assertions.assertThat(stdout).containsPattern("NATIVE_ADDRESS_AND_PORT:[0-9]+:127.0.0.1:[0-9]+");
 +        Assertions.assertThat(stdout).containsPattern("SSTABLE_VERSIONS:[0-9]+:");
 +        Assertions.assertThat(stdout).containsPattern("STATUS_WITH_PORT:[0-9]+:NORMAL,.+");
 +        Assertions.assertThat(stdout).containsPattern("TOKENS:[0-9]+:<hidden>");
 +
 +        // Make sure heartbeats are detected
 +        Message<NoPayload> echoMessageOut = Message.out(ECHO_REQ, NoPayload.noPayload);
 +        MessagingService.instance().send(echoMessageOut, FBUtilities.getBroadcastAddressAndPort());
 +
 +        String origHeartbeatCount = StringUtils.substringBetween(stdout, "heartbeat:", "\n");
 +        tool = ToolRunner.invokeNodetool("gossipinfo");
 +        tool.assertOnCleanExit();
 +        String newHeartbeatCount = StringUtils.substringBetween(stdout, "heartbeat:", "\n");
 +        assertThat(Integer.parseInt(origHeartbeatCount)).isLessThanOrEqualTo(Integer.parseInt(newHeartbeatCount));
 +    }
 +}
diff --cc test/unit/org/apache/cassandra/tools/nodetool/InvalidateCredentialsCacheTest.java
index 7ed5530,0000000..fbe631b
mode 100644,000000..100644
--- a/test/unit/org/apache/cassandra/tools/nodetool/InvalidateCredentialsCacheTest.java
+++ b/test/unit/org/apache/cassandra/tools/nodetool/InvalidateCredentialsCacheTest.java
@@@ -1,171 -1,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.tools.nodetool;
 +
 +import org.junit.BeforeClass;
 +import org.junit.Test;
- import org.junit.runner.RunWith;
 +
 +import com.datastax.driver.core.EndPoint;
 +import com.datastax.driver.core.PlainTextAuthProvider;
- import org.apache.cassandra.OrderedJUnit4ClassRunner;
 +import org.apache.cassandra.SchemaLoader;
 +import org.apache.cassandra.auth.AuthTestUtils;
 +import org.apache.cassandra.auth.AuthenticatedUser;
 +import org.apache.cassandra.auth.IAuthenticator;
 +import org.apache.cassandra.auth.PasswordAuthenticator;
 +import org.apache.cassandra.cql3.CQLTester;
 +import org.apache.cassandra.tools.ToolRunner;
 +
 +import static org.apache.cassandra.auth.AuthTestUtils.ROLE_A;
 +import static org.apache.cassandra.auth.AuthTestUtils.ROLE_B;
 +import static org.apache.cassandra.auth.AuthTestUtils.getRolesReadCount;
 +import static org.assertj.core.api.Assertions.assertThat;
 +
- @RunWith(OrderedJUnit4ClassRunner.class)
 +public class InvalidateCredentialsCacheTest extends CQLTester
 +{
 +    private static IAuthenticator.SaslNegotiator roleANegotiator;
 +    private static IAuthenticator.SaslNegotiator roleBNegotiator;
 +
 +    @BeforeClass
 +    public static void setup() throws Exception
 +    {
 +        SchemaLoader.prepareServer();
 +        AuthTestUtils.LocalCassandraRoleManager roleManager = new AuthTestUtils.LocalCassandraRoleManager();
 +        PasswordAuthenticator authenticator = new AuthTestUtils.LocalPasswordAuthenticator();
 +        SchemaLoader.setupAuth(roleManager,
 +                authenticator,
 +                new AuthTestUtils.LocalCassandraAuthorizer(),
 +                new AuthTestUtils.LocalCassandraNetworkAuthorizer());
 +
 +        roleManager.createRole(AuthenticatedUser.SYSTEM_USER, ROLE_A, AuthTestUtils.getLoginRoleOprions());
 +        roleManager.createRole(AuthenticatedUser.SYSTEM_USER, ROLE_B, AuthTestUtils.getLoginRoleOprions());
 +
 +        roleANegotiator = authenticator.newSaslNegotiator(null);
 +        roleANegotiator.evaluateResponse(new PlainTextAuthProvider(ROLE_A.getRoleName(), "ignored")
 +                .newAuthenticator((EndPoint) null, null)
 +                .initialResponse());
 +        roleBNegotiator = authenticator.newSaslNegotiator(null);
 +        roleBNegotiator.evaluateResponse(new PlainTextAuthProvider(ROLE_B.getRoleName(), "ignored")
 +                .newAuthenticator((EndPoint) null, null)
 +                .initialResponse());
 +
 +        startJMXServer();
 +    }
 +
 +    @Test
 +    @SuppressWarnings("SingleCharacterStringConcatenation")
 +    public void testMaybeChangeDocs()
 +    {
 +        // If you added, modified options or help, please update docs if necessary
 +        ToolRunner.ToolResult tool = ToolRunner.invokeNodetool("help", "invalidatecredentialscache");
 +        tool.assertOnCleanExit();
 +
 +        String help =   "NAME\n" +
 +                        "        nodetool invalidatecredentialscache - Invalidate the credentials cache\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>)] invalidatecredentialscache\n" +
 +                        "                [--] [<role>...]\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" +
 +                        "            This option can be used to separate command-line options from the\n" +
 +                        "            list of argument, (useful when arguments might be mistaken for\n" +
 +                        "            command-line options\n" +
 +                        "\n" +
 +                        "        [<role>...]\n" +
 +                        "            List of roles to invalidate. By default, all roles\n" +
 +                        "\n" +
 +                        "\n";
 +        assertThat(tool.getStdout()).isEqualTo(help);
 +    }
 +
 +    @Test
 +    public void testInvalidateSingleCredential()
 +    {
 +        // cache credential
 +        roleANegotiator.getAuthenticatedUser();
 +        long originalReadsCount = getRolesReadCount();
 +
 +        // enure credential is cached
 +        assertThat(roleANegotiator.getAuthenticatedUser()).isEqualTo(new AuthenticatedUser(ROLE_A.getRoleName()));
 +        assertThat(originalReadsCount).isEqualTo(getRolesReadCount());
 +
 +        // invalidate credential
 +        ToolRunner.ToolResult tool = ToolRunner.invokeNodetool("invalidatecredentialscache", ROLE_A.getRoleName());
 +        tool.assertOnCleanExit();
 +        assertThat(tool.getStdout()).isEmpty();
 +
 +        // ensure credential is reloaded
 +        assertThat(roleANegotiator.getAuthenticatedUser()).isEqualTo(new AuthenticatedUser(ROLE_A.getRoleName()));
 +        assertThat(originalReadsCount).isLessThan(getRolesReadCount());
 +    }
 +
 +    @Test
 +    public void testInvalidateAllCredentials()
 +    {
 +        // cache credentials
 +        roleANegotiator.getAuthenticatedUser();
 +        roleBNegotiator.getAuthenticatedUser();
 +        long originalReadsCount = getRolesReadCount();
 +
 +        // enure credentials are cached
 +        assertThat(roleANegotiator.getAuthenticatedUser()).isEqualTo(new AuthenticatedUser(ROLE_A.getRoleName()));
 +        assertThat(roleBNegotiator.getAuthenticatedUser()).isEqualTo(new AuthenticatedUser(ROLE_B.getRoleName()));
 +        assertThat(originalReadsCount).isEqualTo(getRolesReadCount());
 +
 +        // invalidate both credentials
 +        ToolRunner.ToolResult tool = ToolRunner.invokeNodetool("invalidatecredentialscache");
 +        tool.assertOnCleanExit();
 +        assertThat(tool.getStdout()).isEmpty();
 +
 +        // ensure credential for roleA is reloaded
 +        assertThat(roleANegotiator.getAuthenticatedUser()).isEqualTo(new AuthenticatedUser(ROLE_A.getRoleName()));
 +        long readsCountAfterFirstReLoad = getRolesReadCount();
 +        assertThat(originalReadsCount).isLessThan(readsCountAfterFirstReLoad);
 +
 +        // ensure credential for roleB is reloaded
 +        assertThat(roleBNegotiator.getAuthenticatedUser()).isEqualTo(new AuthenticatedUser(ROLE_B.getRoleName()));
 +        long readsCountAfterSecondReLoad = getRolesReadCount();
 +        assertThat(readsCountAfterFirstReLoad).isLessThan(readsCountAfterSecondReLoad);
 +    }
 +}
diff --cc test/unit/org/apache/cassandra/tools/nodetool/InvalidateJmxPermissionsCacheTest.java
index 81fa2c5,0000000..f412147
mode 100644,000000..100644
--- a/test/unit/org/apache/cassandra/tools/nodetool/InvalidateJmxPermissionsCacheTest.java
+++ b/test/unit/org/apache/cassandra/tools/nodetool/InvalidateJmxPermissionsCacheTest.java
@@@ -1,192 -1,0 +1,189 @@@
 +/*
 + * 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 java.util.Set;
 +import javax.security.auth.Subject;
 +
 +import org.junit.BeforeClass;
 +import org.junit.Test;
- import org.junit.runner.RunWith;
 +
- import org.apache.cassandra.OrderedJUnit4ClassRunner;
 +import org.apache.cassandra.SchemaLoader;
 +import org.apache.cassandra.auth.AuthTestUtils;
 +import org.apache.cassandra.auth.AuthenticatedUser;
 +import org.apache.cassandra.auth.CassandraPrincipal;
 +import org.apache.cassandra.auth.JMXResource;
 +import org.apache.cassandra.auth.Permission;
 +import org.apache.cassandra.auth.jmx.AuthorizationProxy;
 +import org.apache.cassandra.cql3.CQLTester;
 +import org.apache.cassandra.tools.ToolRunner;
 +
 +import static org.apache.cassandra.auth.AuthTestUtils.ROLE_A;
 +import static org.apache.cassandra.auth.AuthTestUtils.ROLE_B;
 +import static org.apache.cassandra.auth.AuthTestUtils.getRolePermissionsReadCount;
 +import static org.assertj.core.api.Assertions.assertThat;
 +
- @RunWith(OrderedJUnit4ClassRunner.class)
 +public class InvalidateJmxPermissionsCacheTest extends CQLTester
 +{
 +    private static final AuthorizationProxy authorizationProxy = new NoAuthSetupAuthorizationProxy();
 +
 +    @BeforeClass
 +    public static void setup() throws Exception
 +    {
 +        SchemaLoader.prepareServer();
 +        AuthTestUtils.LocalCassandraRoleManager roleManager = new AuthTestUtils.LocalCassandraRoleManager();
 +        AuthTestUtils.LocalCassandraAuthorizer authorizer = new AuthTestUtils.LocalCassandraAuthorizer();
 +        SchemaLoader.setupAuth(roleManager,
 +                new AuthTestUtils.LocalPasswordAuthenticator(),
 +                authorizer,
 +                new AuthTestUtils.LocalCassandraNetworkAuthorizer());
 +
 +        JMXResource rootJmxResource = JMXResource.root();
 +        Set<Permission> jmxPermissions = rootJmxResource.applicablePermissions();
 +
 +        roleManager.createRole(AuthenticatedUser.SYSTEM_USER, ROLE_A, AuthTestUtils.getLoginRoleOprions());
 +        authorizer.grant(AuthenticatedUser.SYSTEM_USER, jmxPermissions, rootJmxResource, ROLE_A);
 +
 +        roleManager.createRole(AuthenticatedUser.SYSTEM_USER, ROLE_B, AuthTestUtils.getLoginRoleOprions());
 +        authorizer.grant(AuthenticatedUser.SYSTEM_USER, jmxPermissions, rootJmxResource, ROLE_B);
 +
 +        startJMXServer();
 +    }
 +
 +    @Test
 +    @SuppressWarnings("SingleCharacterStringConcatenation")
 +    public void testMaybeChangeDocs()
 +    {
 +        // If you added, modified options or help, please update docs if necessary
 +        ToolRunner.ToolResult tool = ToolRunner.invokeNodetool("help", "invalidatejmxpermissionscache");
 +        tool.assertOnCleanExit();
 +
 +        String help =   "NAME\n" +
 +                        "        nodetool invalidatejmxpermissionscache - Invalidate the JMX permissions\n" +
 +                        "        cache\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>)] invalidatejmxpermissionscache\n" +
 +                        "                [--] [<role>...]\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" +
 +                        "            This option can be used to separate command-line options from the\n" +
 +                        "            list of argument, (useful when arguments might be mistaken for\n" +
 +                        "            command-line options\n" +
 +                        "\n" +
 +                        "        [<role>...]\n" +
 +                        "            List of roles to invalidate. By default, all roles\n" +
 +                        "\n" +
 +                        "\n";
 +        assertThat(tool.getStdout()).isEqualTo(help);
 +    }
 +
 +    @Test
 +    public void testInvalidateSingleJMXPermission()
 +    {
 +        Subject userSubject = subject(ROLE_A.getRoleName());
 +
 +        // cache role permission
 +        authorizationProxy.authorize(userSubject, "queryNames", null);
 +        long originalReadsCount = getRolePermissionsReadCount();
 +
 +        // enure role permission is cached
 +        assertThat(authorizationProxy.authorize(userSubject, "queryNames", null)).isTrue();
 +        assertThat(originalReadsCount).isEqualTo(getRolePermissionsReadCount());
 +
 +        // invalidate role permission
 +        ToolRunner.ToolResult tool = ToolRunner.invokeNodetool("invalidatejmxpermissionscache", ROLE_A.getRoleName());
 +        tool.assertOnCleanExit();
 +        assertThat(tool.getStdout()).isEmpty();
 +
 +        // ensure role permission is reloaded
 +        assertThat(authorizationProxy.authorize(userSubject, "queryNames", null)).isTrue();
 +        assertThat(originalReadsCount).isLessThan(getRolePermissionsReadCount());
 +    }
 +
 +    @Test
 +    public void testInvalidateAllJMXPermissions()
 +    {
 +        Subject roleASubject = subject(ROLE_A.getRoleName());
 +        Subject roleBSubject = subject(ROLE_B.getRoleName());
 +
 +        // cache role permissions
 +        authorizationProxy.authorize(roleASubject, "queryNames", null);
 +        authorizationProxy.authorize(roleBSubject, "queryNames", null);
 +        long originalReadsCount = getRolePermissionsReadCount();
 +
 +        // enure role permissions are cached
 +        assertThat(authorizationProxy.authorize(roleASubject, "queryNames", null)).isTrue();
 +        assertThat(authorizationProxy.authorize(roleBSubject, "queryNames", null)).isTrue();
 +        assertThat(originalReadsCount).isEqualTo(getRolePermissionsReadCount());
 +
 +        // invalidate both role permissions
 +        ToolRunner.ToolResult tool = ToolRunner.invokeNodetool("invalidatejmxpermissionscache");
 +        tool.assertOnCleanExit();
 +        assertThat(tool.getStdout()).isEmpty();
 +
 +        // ensure role permission for roleA is reloaded
 +        assertThat(authorizationProxy.authorize(roleASubject, "queryNames", null)).isTrue();
 +        long readsCountAfterFirstReLoad = getRolePermissionsReadCount();
 +        assertThat(originalReadsCount).isLessThan(readsCountAfterFirstReLoad);
 +
 +        // ensure role permission for roleB is reloaded
 +        assertThat(authorizationProxy.authorize(roleBSubject, "queryNames", null)).isTrue();
 +        long readsCountAfterSecondReLoad = getRolePermissionsReadCount();
 +        assertThat(readsCountAfterFirstReLoad).isLessThan(readsCountAfterSecondReLoad);
 +    }
 +
 +    private static Subject subject(String roleName)
 +    {
 +        Subject subject = new Subject();
 +        subject.getPrincipals().add(new CassandraPrincipal(roleName));
 +        return subject;
 +    }
 +
 +    private static class NoAuthSetupAuthorizationProxy extends AuthorizationProxy
 +    {
 +        public NoAuthSetupAuthorizationProxy()
 +        {
 +            super();
 +            this.isAuthSetupComplete = () -> true;
 +        }
 +    }
 +}
diff --cc test/unit/org/apache/cassandra/tools/nodetool/InvalidateNetworkPermissionsCacheTest.java
index cef29b3,0000000..8200a80
mode 100644,000000..100644
--- a/test/unit/org/apache/cassandra/tools/nodetool/InvalidateNetworkPermissionsCacheTest.java
+++ b/test/unit/org/apache/cassandra/tools/nodetool/InvalidateNetworkPermissionsCacheTest.java
@@@ -1,160 -1,0 +1,157 @@@
 +/*
 + * 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.SchemaLoader;
 +import org.apache.cassandra.auth.AuthTestUtils;
 +import org.apache.cassandra.auth.AuthenticatedUser;
 +import org.apache.cassandra.cql3.CQLTester;
 +import org.apache.cassandra.tools.ToolRunner;
 +
 +import static org.apache.cassandra.auth.AuthTestUtils.ROLE_A;
 +import static org.apache.cassandra.auth.AuthTestUtils.ROLE_B;
 +import static org.apache.cassandra.auth.AuthTestUtils.getNetworkPermissionsReadCount;
 +import static org.assertj.core.api.Assertions.assertThat;
 +
- @RunWith(OrderedJUnit4ClassRunner.class)
 +public class InvalidateNetworkPermissionsCacheTest extends CQLTester
 +{
 +    @BeforeClass
 +    public static void setup() throws Exception
 +    {
 +        SchemaLoader.prepareServer();
 +        AuthTestUtils.LocalCassandraRoleManager roleManager = new AuthTestUtils.LocalCassandraRoleManager();
 +        SchemaLoader.setupAuth(roleManager,
 +                new AuthTestUtils.LocalPasswordAuthenticator(),
 +                new AuthTestUtils.LocalCassandraAuthorizer(),
 +                new AuthTestUtils.LocalCassandraNetworkAuthorizer());
 +
 +        roleManager.createRole(AuthenticatedUser.SYSTEM_USER, ROLE_A, AuthTestUtils.getLoginRoleOprions());
 +        roleManager.createRole(AuthenticatedUser.SYSTEM_USER, ROLE_B, AuthTestUtils.getLoginRoleOprions());
 +
 +        startJMXServer();
 +    }
 +
 +    @Test
 +    @SuppressWarnings("SingleCharacterStringConcatenation")
 +    public void testMaybeChangeDocs()
 +    {
 +        // If you added, modified options or help, please update docs if necessary
 +        ToolRunner.ToolResult tool = ToolRunner.invokeNodetool("help", "invalidatenetworkpermissionscache");
 +        tool.assertOnCleanExit();
 +
 +        String help =   "NAME\n" +
 +                        "        nodetool invalidatenetworkpermissionscache - Invalidate the network\n" +
 +                        "        permissions cache\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>)]\n" +
 +                        "                invalidatenetworkpermissionscache [--] [<role>...]\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" +
 +                        "            This option can be used to separate command-line options from the\n" +
 +                        "            list of argument, (useful when arguments might be mistaken for\n" +
 +                        "            command-line options\n" +
 +                        "\n" +
 +                        "        [<role>...]\n" +
 +                        "            List of roles to invalidate. By default, all roles\n" +
 +                        "\n" +
 +                        "\n";
 +        assertThat(tool.getStdout()).isEqualTo(help);
 +    }
 +
 +    @Test
 +    public void testInvalidateSingleNetworkPermission()
 +    {
 +        AuthenticatedUser role = new AuthenticatedUser(ROLE_A.getRoleName());
 +
 +        // cache network permission
 +        role.hasLocalAccess();
 +        long originalReadsCount = getNetworkPermissionsReadCount();
 +
 +        // enure network permission is cached
 +        assertThat(role.hasLocalAccess()).isTrue();
 +        assertThat(originalReadsCount).isEqualTo(getNetworkPermissionsReadCount());
 +
 +        // invalidate network permission
 +        ToolRunner.ToolResult tool = ToolRunner.invokeNodetool("invalidatenetworkpermissionscache", ROLE_A.getRoleName());
 +        tool.assertOnCleanExit();
 +        assertThat(tool.getStdout()).isEmpty();
 +
 +        // ensure network permission is reloaded
 +        assertThat(role.hasLocalAccess()).isTrue();
 +        assertThat(originalReadsCount).isLessThan(getNetworkPermissionsReadCount());
 +    }
 +
 +    @Test
 +    public void testInvalidateAllNetworkPermissions()
 +    {
 +        AuthenticatedUser roleA = new AuthenticatedUser(ROLE_A.getRoleName());
 +        AuthenticatedUser roleB = new AuthenticatedUser(ROLE_B.getRoleName());
 +
 +        // cache network permissions
 +        roleA.hasLocalAccess();
 +        roleB.hasLocalAccess();
 +        long originalReadsCount = getNetworkPermissionsReadCount();
 +
 +        // enure network permissions are cached
 +        assertThat(roleA.hasLocalAccess()).isTrue();
 +        assertThat(roleB.hasLocalAccess()).isTrue();
 +        assertThat(originalReadsCount).isEqualTo(getNetworkPermissionsReadCount());
 +
 +        // invalidate both network permissions
 +        ToolRunner.ToolResult tool = ToolRunner.invokeNodetool("invalidatenetworkpermissionscache");
 +        tool.assertOnCleanExit();
 +        assertThat(tool.getStdout()).isEmpty();
 +
 +        // ensure network permission for roleA is reloaded
 +        assertThat(roleA.hasLocalAccess()).isTrue();
 +        long readsCountAfterFirstReLoad = getNetworkPermissionsReadCount();
 +        assertThat(originalReadsCount).isLessThan(readsCountAfterFirstReLoad);
 +
 +        // ensure network permission for roleB is reloaded
 +        assertThat(roleB.hasLocalAccess()).isTrue();
 +        long readsCountAfterSecondReLoad = getNetworkPermissionsReadCount();
 +        assertThat(readsCountAfterFirstReLoad).isLessThan(readsCountAfterSecondReLoad);
 +    }
 +}
diff --cc test/unit/org/apache/cassandra/tools/nodetool/InvalidatePermissionsCacheTest.java
index caaabf2,0000000..4b23a6d
mode 100644,000000..100644
--- a/test/unit/org/apache/cassandra/tools/nodetool/InvalidatePermissionsCacheTest.java
+++ b/test/unit/org/apache/cassandra/tools/nodetool/InvalidatePermissionsCacheTest.java
@@@ -1,317 -1,0 +1,314 @@@
 +/*
 + * 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 java.util.ArrayList;
 +import java.util.Arrays;
 +import java.util.Collections;
 +import java.util.List;
 +import java.util.Set;
 +
 +import org.apache.commons.lang3.StringUtils;
 +import org.junit.BeforeClass;
 +import org.junit.Test;
- import org.junit.runner.RunWith;
 +
- import org.apache.cassandra.OrderedJUnit4ClassRunner;
 +import org.apache.cassandra.SchemaLoader;
 +import org.apache.cassandra.auth.AuthTestUtils;
 +import org.apache.cassandra.auth.AuthenticatedUser;
 +import org.apache.cassandra.auth.DataResource;
 +import org.apache.cassandra.auth.FunctionResource;
 +import org.apache.cassandra.auth.IResource;
 +import org.apache.cassandra.auth.JMXResource;
 +import org.apache.cassandra.auth.Permission;
 +import org.apache.cassandra.auth.RoleResource;
 +import org.apache.cassandra.config.DatabaseDescriptor;
 +import org.apache.cassandra.cql3.CQLTester;
 +import org.apache.cassandra.db.marshal.Int32Type;
 +import org.apache.cassandra.tools.ToolRunner;
 +
 +import static org.apache.cassandra.auth.AuthTestUtils.ROLE_A;
 +import static org.apache.cassandra.auth.AuthTestUtils.ROLE_B;
 +import static org.apache.cassandra.auth.AuthTestUtils.getRolePermissionsReadCount;
 +import static org.assertj.core.api.Assertions.assertThat;
 +
- @RunWith(OrderedJUnit4ClassRunner.class)
 +public class InvalidatePermissionsCacheTest extends CQLTester
 +{
 +    @BeforeClass
 +    public static void setup() throws Exception
 +    {
 +        SchemaLoader.prepareServer();
 +        AuthTestUtils.LocalCassandraRoleManager roleManager = new AuthTestUtils.LocalCassandraRoleManager();
 +        AuthTestUtils.LocalCassandraAuthorizer authorizer = new AuthTestUtils.LocalCassandraAuthorizer();
 +        SchemaLoader.setupAuth(roleManager,
 +                new AuthTestUtils.LocalPasswordAuthenticator(),
 +                authorizer,
 +                new AuthTestUtils.LocalCassandraNetworkAuthorizer());
 +
 +        roleManager.createRole(AuthenticatedUser.SYSTEM_USER, ROLE_A, AuthTestUtils.getLoginRoleOprions());
 +        roleManager.createRole(AuthenticatedUser.SYSTEM_USER, ROLE_B, AuthTestUtils.getLoginRoleOprions());
 +
 +        List<IResource> resources = Arrays.asList(
 +                DataResource.root(),
 +                DataResource.keyspace(KEYSPACE),
 +                DataResource.table(KEYSPACE, "t1"),
 +                RoleResource.root(),
 +                RoleResource.role("role_x"),
 +                FunctionResource.root(),
 +                FunctionResource.keyspace(KEYSPACE),
 +                // Particular function is excluded from here and covered by a separate test because in order to grant
 +                // permissions we need to have a function registered. However, the function cannot be registered via
 +                // CQLTester.createFunction from static contex. That's why we initialize it in a separate test case.
 +                JMXResource.root(),
 +                JMXResource.mbean("org.apache.cassandra.auth:type=*"));
 +
 +        for (IResource resource : resources)
 +        {
 +            Set<Permission> permissions = resource.applicablePermissions();
 +            authorizer.grant(AuthenticatedUser.SYSTEM_USER, permissions, resource, ROLE_A);
 +            authorizer.grant(AuthenticatedUser.SYSTEM_USER, permissions, resource, ROLE_B);
 +        }
 +
 +        startJMXServer();
 +    }
 +
 +    @Test
 +    @SuppressWarnings("SingleCharacterStringConcatenation")
 +    public void testMaybeChangeDocs()
 +    {
 +        // If you added, modified options or help, please update docs if necessary
 +        ToolRunner.ToolResult tool = ToolRunner.invokeNodetool("help", "invalidatepermissionscache");
 +        tool.assertOnCleanExit();
 +
 +        String help =   "NAME\n" +
 +                        "        nodetool invalidatepermissionscache - Invalidate the permissions cache\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>)] invalidatepermissionscache\n" +
 +                        "                [--all-functions] [--all-keyspaces] [--all-mbeans] [--all-roles]\n" +
 +                        "                [--function <function>]\n" +
 +                        "                [--functions-in-keyspace <functions-in-keyspace>]\n" +
 +                        "                [--keyspace <keyspace>] [--mbean <mbean>] [--role <role>]\n" +
 +                        "                [--table <table>] [--] [<user>]\n" +
 +                        "\n" +
 +                        "OPTIONS\n" +
 +                        "        --all-functions\n" +
 +                        "            Invalidate permissions for 'ALL FUNCTIONS'\n" +
 +                        "\n" +
 +                        "        --all-keyspaces\n" +
 +                        "            Invalidate permissions for 'ALL KEYSPACES'\n" +
 +                        "\n" +
 +                        "        --all-mbeans\n" +
 +                        "            Invalidate permissions for 'ALL MBEANS'\n" +
 +                        "\n" +
 +                        "        --all-roles\n" +
 +                        "            Invalidate permissions for 'ALL ROLES'\n" +
 +                        "\n" +
 +                        "        --function <function>\n" +
 +                        "            Function to invalidate permissions for (you must specify\n" +
 +                        "            --functions-in-keyspace for using this option; function format:\n" +
 +                        "            name[arg1^..^agrN], for example: foo[Int32Type^DoubleType])\n" +
 +                        "\n" +
 +                        "        --functions-in-keyspace <functions-in-keyspace>\n" +
 +                        "            Keyspace to invalidate permissions for\n" +
 +                        "\n" +
 +                        "        -h <host>, --host <host>\n" +
 +                        "            Node hostname or ip address\n" +
 +                        "\n" +
 +                        "        --keyspace <keyspace>\n" +
 +                        "            Keyspace to invalidate permissions for\n" +
 +                        "\n" +
 +                        "        --mbean <mbean>\n" +
 +                        "            MBean to invalidate permissions for\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" +
 +                        "        --role <role>\n" +
 +                        "            Role to invalidate permissions for\n" +
 +                        "\n" +
 +                        "        --table <table>\n" +
 +                        "            Table to invalidate permissions for (you must specify --keyspace for\n" +
 +                        "            using this option)\n" +
 +                        "\n" +
 +                        "        -u <username>, --username <username>\n" +
 +                        "            Remote jmx agent username\n" +
 +                        "\n" +
 +                        "        --\n" +
 +                        "            This option can be used to separate command-line options from the\n" +
 +                        "            list of argument, (useful when arguments might be mistaken for\n" +
 +                        "            command-line options\n" +
 +                        "\n" +
 +                        "        [<user>]\n" +
 +                        "            A specific user for whom permissions need to be invalidated\n" +
 +                        "\n" +
 +                        "\n";
 +        assertThat(tool.getStdout()).isEqualTo(help);
 +    }
 +
 +    @Test
 +    public void testInvalidatePermissionsWithIncorrectParameters()
 +    {
 +        ToolRunner.ToolResult tool = ToolRunner.invokeNodetool("invalidatepermissionscache", "--all-keyspaces");
 +        assertThat(tool.getExitCode()).isEqualTo(1);
 +        assertThat(tool.getStdout())
 +                .isEqualTo(wrapByDefaultNodetoolMessage("No options allowed without a <user> being specified"));
 +        assertThat(tool.getStderr()).isEmpty();
 +
 +        tool = ToolRunner.invokeNodetool("invalidatepermissionscache", "user1", "--invalid-option");
 +        assertThat(tool.getExitCode()).isEqualTo(1);
 +        assertThat(tool.getStdout())
 +                .isEqualTo(wrapByDefaultNodetoolMessage("A single <user> is only supported / you have a typo in the options spelling"));
 +        assertThat(tool.getStderr()).isEmpty();
 +
 +        tool = ToolRunner.invokeNodetool("invalidatepermissionscache", "user1", "--table", "t1");
 +        assertThat(tool.getExitCode()).isEqualTo(1);
 +        assertThat(tool.getStdout())
 +                .isEqualTo(wrapByDefaultNodetoolMessage("--table option should be passed along with --keyspace option"));
 +        assertThat(tool.getStderr()).isEmpty();
 +
 +        tool = ToolRunner.invokeNodetool("invalidatepermissionscache", "user1", "--function", "f[Int32Type]");
 +        assertThat(tool.getExitCode()).isEqualTo(1);
 +        assertThat(tool.getStdout())
 +                .isEqualTo(wrapByDefaultNodetoolMessage("--function option should be passed along with --functions-in-keyspace option"));
 +        assertThat(tool.getStderr()).isEmpty();
 +
 +        tool = ToolRunner.invokeNodetool("invalidatepermissionscache", "user1", "--functions-in-keyspace",
 +                KEYSPACE, "--function", "f[x]");
 +        assertThat(tool.getExitCode()).isEqualTo(1);
 +        assertThat(tool.getStdout())
 +                .isEqualTo(wrapByDefaultNodetoolMessage("An error was encountered when looking up function definition; Unable to find abstract-type class 'org.apache.cassandra.db.marshal.x'"));
 +        assertThat(tool.getStderr()).isEmpty();
 +    }
 +
 +    @Test
 +    public void testInvalidatePermissionsForEveryResourceExceptFunction()
 +    {
 +        assertInvalidation(DataResource.root(), Collections.singletonList("--all-keyspaces"));
 +        assertInvalidation(DataResource.keyspace(KEYSPACE), Arrays.asList("--keyspace", KEYSPACE));
 +        assertInvalidation(DataResource.table(KEYSPACE, "t1"),
 +                Arrays.asList("--keyspace", KEYSPACE, "--table", "t1"));
 +        assertInvalidation(RoleResource.root(), Collections.singletonList("--all-roles"));
 +        assertInvalidation(RoleResource.role("role_x"), Arrays.asList("--role", "role_x"));
 +        assertInvalidation(FunctionResource.root(), Collections.singletonList("--all-functions"));
 +        assertInvalidation(FunctionResource.keyspace(KEYSPACE), Arrays.asList("--functions-in-keyspace", KEYSPACE));
 +        assertInvalidation(JMXResource.root(), Collections.singletonList("--all-mbeans"));
 +        assertInvalidation(JMXResource.mbean("org.apache.cassandra.auth:type=*"),
 +                Arrays.asList("--mbean", "org.apache.cassandra.auth:type=*"));
 +    }
 +
 +    @Test
 +    public void testInvalidatePermissionsForFunction() throws Throwable
 +    {
 +        String keyspaceAndFunctionName = createFunction(KEYSPACE, "int",
 +                " CREATE FUNCTION %s (val int)" +
 +                        " CALLED ON NULL INPUT" +
 +                        " RETURNS int" +
 +                        " LANGUAGE java" +
 +                        " AS 'return val;'");
 +        String functionName = StringUtils.split(keyspaceAndFunctionName, ".")[1];
 +
 +        FunctionResource resource = FunctionResource.function(KEYSPACE, functionName, Collections.singletonList(Int32Type.instance));
 +        Set<Permission> permissions = resource.applicablePermissions();
 +        DatabaseDescriptor.getAuthorizer().grant(AuthenticatedUser.SYSTEM_USER, permissions, resource, ROLE_A);
 +        DatabaseDescriptor.getAuthorizer().grant(AuthenticatedUser.SYSTEM_USER, permissions, resource, ROLE_B);
 +
 +        assertInvalidation(resource,
 +                Arrays.asList("--functions-in-keyspace", KEYSPACE, "--function", functionName + "[Int32Type]"));
 +    }
 +
 +    private void assertInvalidation(IResource resource, List<String> options)
 +    {
 +        Set<Permission> dataPermissions = resource.applicablePermissions();
 +
 +        AuthenticatedUser role = new AuthenticatedUser(ROLE_A.getRoleName());
 +
 +        // cache permission
 +        role.getPermissions(resource);
 +        long originalReadsCount = getRolePermissionsReadCount();
 +
 +        // enure permission is cached
 +        assertThat(role.getPermissions(resource)).isEqualTo(dataPermissions);
 +        assertThat(originalReadsCount).isEqualTo(getRolePermissionsReadCount());
 +
 +        // invalidate permission
 +        List<String> args = new ArrayList<>();
 +        args.add("invalidatepermissionscache");
 +        args.add(ROLE_A.getRoleName());
 +        args.addAll(options);
 +        ToolRunner.ToolResult tool = ToolRunner.invokeNodetool(args);
 +        tool.assertOnCleanExit();
 +        assertThat(tool.getStdout()).isEmpty();
 +
 +        // ensure permission is reloaded
 +        assertThat(role.getPermissions(resource)).isEqualTo(dataPermissions);
 +        assertThat(originalReadsCount).isLessThan(getRolePermissionsReadCount());
 +    }
 +
 +    @Test
 +    public void testInvalidatePermissionsForAllUsers()
 +    {
 +        DataResource rootDataResource = DataResource.root();
 +        Set<Permission> dataPermissions = rootDataResource.applicablePermissions();
 +
 +        AuthenticatedUser roleA = new AuthenticatedUser(ROLE_A.getRoleName());
 +        AuthenticatedUser roleB = new AuthenticatedUser(ROLE_B.getRoleName());
 +
 +        // cache permissions
 +        roleA.getPermissions(rootDataResource);
 +        roleB.getPermissions(rootDataResource);
 +        long originalReadsCount = getRolePermissionsReadCount();
 +
 +        // enure permissions are cached
 +        assertThat(roleA.getPermissions(rootDataResource)).isEqualTo(dataPermissions);
 +        assertThat(roleB.getPermissions(rootDataResource)).isEqualTo(dataPermissions);
 +        assertThat(originalReadsCount).isEqualTo(getRolePermissionsReadCount());
 +
 +        // invalidate both permissions
 +        ToolRunner.ToolResult tool = ToolRunner.invokeNodetool("invalidatepermissionscache");
 +        tool.assertOnCleanExit();
 +        assertThat(tool.getStdout()).isEmpty();
 +
 +        // ensure permission for roleA is reloaded
 +        assertThat(roleA.getPermissions(rootDataResource)).isEqualTo(dataPermissions);
 +        long readsCountAfterFirstReLoad = getRolePermissionsReadCount();
 +        assertThat(originalReadsCount).isLessThan(readsCountAfterFirstReLoad);
 +
 +        // ensure permission for roleB is reloaded
 +        assertThat(roleB.getPermissions(rootDataResource)).isEqualTo(dataPermissions);
 +        long readsCountAfterSecondReLoad = getRolePermissionsReadCount();
 +        assertThat(readsCountAfterFirstReLoad).isLessThan(readsCountAfterSecondReLoad);
 +    }
 +
 +    private String wrapByDefaultNodetoolMessage(String s)
 +    {
 +        return "nodetool: " + s + "\nSee 'nodetool help' or 'nodetool help <command>'.\n";
 +    }
 +}
diff --cc test/unit/org/apache/cassandra/tools/nodetool/InvalidateRolesCacheTest.java
index 80596b3,0000000..36eb64e
mode 100644,000000..100644
--- a/test/unit/org/apache/cassandra/tools/nodetool/InvalidateRolesCacheTest.java
+++ b/test/unit/org/apache/cassandra/tools/nodetool/InvalidateRolesCacheTest.java
@@@ -1,159 -1,0 +1,156 @@@
 +/*
 + * 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.SchemaLoader;
 +import org.apache.cassandra.auth.AuthTestUtils;
 +import org.apache.cassandra.auth.AuthenticatedUser;
 +import org.apache.cassandra.cql3.CQLTester;
 +import org.apache.cassandra.tools.ToolRunner;
 +
 +import static org.apache.cassandra.auth.AuthTestUtils.ROLE_A;
 +import static org.apache.cassandra.auth.AuthTestUtils.ROLE_B;
 +import static org.apache.cassandra.auth.AuthTestUtils.getRolesReadCount;
 +import static org.assertj.core.api.Assertions.assertThat;
 +
- @RunWith(OrderedJUnit4ClassRunner.class)
 +public class InvalidateRolesCacheTest extends CQLTester
 +{
 +    @BeforeClass
 +    public static void setup() throws Exception
 +    {
 +        SchemaLoader.prepareServer();
 +        AuthTestUtils.LocalCassandraRoleManager roleManager = new AuthTestUtils.LocalCassandraRoleManager();
 +        SchemaLoader.setupAuth(roleManager,
 +                new AuthTestUtils.LocalPasswordAuthenticator(),
 +                new AuthTestUtils.LocalCassandraAuthorizer(),
 +                new AuthTestUtils.LocalCassandraNetworkAuthorizer());
 +
 +        roleManager.createRole(AuthenticatedUser.SYSTEM_USER, ROLE_A, AuthTestUtils.getLoginRoleOprions());
 +        roleManager.createRole(AuthenticatedUser.SYSTEM_USER, ROLE_B, AuthTestUtils.getLoginRoleOprions());
 +
 +        startJMXServer();
 +    }
 +
 +    @Test
 +    @SuppressWarnings("SingleCharacterStringConcatenation")
 +    public void testMaybeChangeDocs()
 +    {
 +        // If you added, modified options or help, please update docs if necessary
 +        ToolRunner.ToolResult tool = ToolRunner.invokeNodetool("help", "invalidaterolescache");
 +        tool.assertOnCleanExit();
 +
 +        String help =   "NAME\n" +
 +                        "        nodetool invalidaterolescache - Invalidate the roles cache\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>)] invalidaterolescache [--]\n" +
 +                        "                [<role>...]\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" +
 +                        "            This option can be used to separate command-line options from the\n" +
 +                        "            list of argument, (useful when arguments might be mistaken for\n" +
 +                        "            command-line options\n" +
 +                        "\n" +
 +                        "        [<role>...]\n" +
 +                        "            List of roles to invalidate. By default, all roles\n" +
 +                        "\n" +
 +                        "\n";
 +        assertThat(tool.getStdout()).isEqualTo(help);
 +    }
 +
 +    @Test
 +    public void testInvalidateSingleRole()
 +    {
 +        AuthenticatedUser role = new AuthenticatedUser(ROLE_A.getRoleName());
 +
 +        // cache role
 +        role.canLogin();
 +        long originalReadsCount = getRolesReadCount();
 +
 +        // enure role is cached
 +        assertThat(role.canLogin()).isTrue();
 +        assertThat(originalReadsCount).isEqualTo(getRolesReadCount());
 +
 +        // invalidate role
 +        ToolRunner.ToolResult tool = ToolRunner.invokeNodetool("invalidaterolescache", ROLE_A.getRoleName());
 +        tool.assertOnCleanExit();
 +        assertThat(tool.getStdout()).isEmpty();
 +
 +        // ensure role is reloaded
 +        assertThat(role.canLogin()).isTrue();
 +        assertThat(originalReadsCount).isLessThan(getRolesReadCount());
 +    }
 +
 +    @Test
 +    public void testInvalidateAllRoles()
 +    {
 +        AuthenticatedUser roleA = new AuthenticatedUser(ROLE_A.getRoleName());
 +        AuthenticatedUser roleB = new AuthenticatedUser(ROLE_B.getRoleName());
 +
 +        // cache roles
 +        roleA.canLogin();
 +        roleB.canLogin();
 +        long originalReadsCount = getRolesReadCount();
 +
 +        // enure roles are cached
 +        assertThat(roleA.canLogin()).isTrue();
 +        assertThat(roleB.canLogin()).isTrue();
 +        assertThat(originalReadsCount).isEqualTo(getRolesReadCount());
 +
 +        // invalidate both roles
 +        ToolRunner.ToolResult tool = ToolRunner.invokeNodetool("invalidaterolescache");
 +        tool.assertOnCleanExit();
 +        assertThat(tool.getStdout()).isEmpty();
 +
 +        // ensure role for roleA is reloaded
 +        assertThat(roleA.canLogin()).isTrue();
 +        long readsCountAfterFirstReLoad = getRolesReadCount();
 +        assertThat(originalReadsCount).isLessThan(readsCountAfterFirstReLoad);
 +
 +        // ensure role for roleB is reloaded
 +        assertThat(roleB.canLogin()).isTrue();
 +        long readsCountAfterSecondReLoad = getRolesReadCount();
 +        assertThat(readsCountAfterFirstReLoad).isLessThan(readsCountAfterSecondReLoad);
 +    }
 +}
diff --cc test/unit/org/apache/cassandra/tools/nodetool/NetStatsTest.java
index 330a555,bcf8704..f8bd530
--- a/test/unit/org/apache/cassandra/tools/nodetool/NetStatsTest.java
+++ b/test/unit/org/apache/cassandra/tools/nodetool/NetStatsTest.java
@@@ -25,11 -25,10 +25,9 @@@ import java.nio.charset.StandardCharset
  import java.util.Collections;
  import java.util.List;
  
 -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.locator.InetAddressAndPort;
  import org.apache.cassandra.net.Message;
@@@ -39,15 -38,20 +37,14 @@@ import org.apache.cassandra.schema.Tabl
  import org.apache.cassandra.streaming.SessionInfo;
  import org.apache.cassandra.streaming.StreamSession.State;
  import org.apache.cassandra.streaming.StreamSummary;
 -import org.apache.cassandra.tools.ToolRunner.ToolResult;
 -import org.apache.cassandra.tools.nodetool.NetStats;
 +import org.apache.cassandra.tools.ToolRunner;
  import org.apache.cassandra.utils.FBUtilities;
 -import org.assertj.core.api.Assertions;
 -import org.hamcrest.CoreMatchers;
  
  import static org.apache.cassandra.net.Verb.ECHO_REQ;
 -import static org.junit.Assert.assertThat;
 +import static org.assertj.core.api.Assertions.assertThat;
  
- @RunWith(OrderedJUnit4ClassRunner.class)
 -public class NodetoolNetStatsTest extends CQLTester
 +public class NetStatsTest extends CQLTester
  {
 -    private static NodeProbe probe;
 -
      @BeforeClass
      public static void setup() throws Exception
      {
diff --cc test/unit/org/apache/cassandra/tools/nodetool/RingTest.java
index b1a2388,bc83f50..00c8bba
--- a/test/unit/org/apache/cassandra/tools/nodetool/RingTest.java
+++ b/test/unit/org/apache/cassandra/tools/nodetool/RingTest.java
@@@ -30,10 -28,14 +28,9 @@@ import org.apache.cassandra.locator.Sim
  import org.apache.cassandra.service.StorageService;
  import org.apache.cassandra.tools.ToolRunner;
  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;
 +import static org.assertj.core.api.Assertions.assertThat;
  
- @RunWith(OrderedJUnit4ClassRunner.class)
  public class RingTest extends CQLTester
  {
      private static String token;
diff --cc test/unit/org/apache/cassandra/tools/nodetool/StatusTest.java
index 18b716e,13acb19..9d8496c
--- a/test/unit/org/apache/cassandra/tools/nodetool/StatusTest.java
+++ b/test/unit/org/apache/cassandra/tools/nodetool/StatusTest.java
@@@ -32,9 -30,10 +30,8 @@@ import org.apache.cassandra.service.Sto
  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;
 +import static org.assertj.core.api.Assertions.assertThat;
  
- @RunWith(OrderedJUnit4ClassRunner.class)
  public class StatusTest extends CQLTester
  {
      private static final Pattern PATTERN = Pattern.compile("\\R");
diff --cc test/unit/org/apache/cassandra/tools/nodetool/TableStatsTest.java
index ccdb16a,6891cad..1ba30f0
--- a/test/unit/org/apache/cassandra/tools/nodetool/TableStatsTest.java
+++ b/test/unit/org/apache/cassandra/tools/nodetool/TableStatsTest.java
@@@ -25,18 -25,23 +25,15 @@@ import java.util.regex.Matcher
  import java.util.regex.Pattern;
  
  import org.apache.commons.lang3.StringUtils;
 -
  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.service.StorageService;
  import org.apache.cassandra.tools.ToolRunner;
 -import org.apache.cassandra.tools.ToolRunner.ToolResult;
 -import org.assertj.core.api.Assertions;
 -import org.hamcrest.CoreMatchers;
  
 -import static org.junit.Assert.assertEquals;
 -import static org.junit.Assert.assertNotEquals;
 -import static org.junit.Assert.assertThat;
 -import static org.junit.Assert.assertTrue;
 +import static org.assertj.core.api.Assertions.assertThat;
  
- @RunWith(OrderedJUnit4ClassRunner.class)
 -public class NodetoolTableStatsTest extends CQLTester
 +public class TableStatsTest extends CQLTester
  {
      @BeforeClass
      public static void setup() throws Exception
diff --cc test/unit/org/apache/cassandra/tools/nodetool/TpStatsTest.java
index edbd6b3,6de2b5b..2b551d3
--- a/test/unit/org/apache/cassandra/tools/nodetool/TpStatsTest.java
+++ b/test/unit/org/apache/cassandra/tools/nodetool/TpStatsTest.java
@@@ -26,12 -26,12 +26,10 @@@ 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;
@@@ -42,10 -43,13 +40,9 @@@ import org.yaml.snakeyaml.Yaml
  
  import static org.apache.cassandra.net.Verb.ECHO_REQ;
  import static org.assertj.core.api.Assertions.assertThat;
 -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
 +public class TpStatsTest extends CQLTester
  {
 -    private static NodeProbe probe;
  
      @BeforeClass
      public static void setup() throws Exception

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cassandra.apache.org
For additional commands, e-mail: commits-help@cassandra.apache.org