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 <[email protected]>
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: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to