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

aweisberg pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cassandra-dtest.git


The following commit(s) were added to refs/heads/master by this push:
     new 7a6d900  If SizeEstimatesRecorder misses a 'onDropTable' notification, 
the size_estimates table will never be cleared for that table
7a6d900 is described below

commit 7a6d9002709628de2bc6af9d987a189b302e4472
Author: Joel Knighton <joel.knigh...@datastax.com>
AuthorDate: Tue Sep 12 17:33:56 2017 -0500

    If SizeEstimatesRecorder misses a 'onDropTable' notification, the 
size_estimates table will never be cleared for that table
    
    Patch by Joel Knighton; Reviewed by Ariel Weisberg for CASSANDRA-14905
    
    Co-authored-by: Joel Knighton <j...@apache.org>
    Co-authored-by: Aleksandr Sorokoumov <aleksandr.sorokou...@gmail.com>
---
 nodetool_test.py    | 20 ++++++++++++++++++
 schema_test.py      | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 tools/assertions.py | 19 +++++++++++++++--
 3 files changed, 96 insertions(+), 4 deletions(-)

diff --git a/nodetool_test.py b/nodetool_test.py
index fb73d30..012780b 100644
--- a/nodetool_test.py
+++ b/nodetool_test.py
@@ -300,6 +300,26 @@ class TestNodetool(Tester):
         session.execute('INSERT INTO test.test (pk, ck, val) VALUES (0, 1, 
2);')
         assert_all(session, 'SELECT pk, ck, val FROM test.test;', [[0, 1, 2]])
 
+    @since('3.0')
+    def test_refresh_size_estimates_clears_invalid_entries(self):
+        """
+        @jira_ticket CASSANDRA-14905
+         nodetool refreshsizeestimates should clear up entries for tables that 
no longer exist
+        """
+        cluster = self.cluster
+        cluster.populate(1)
+        node = cluster.nodelist()[0]
+        cluster.start()
+        session = self.patient_exclusive_cql_connection(node)
+        session.execute("USE system;")
+        # Valid keyspace but invalid table
+        session.execute("INSERT INTO size_estimates (keyspace_name, 
table_name, range_start, range_end, mean_partition_size, partitions_count) 
VALUES ('system_auth', 'bad_table', '-5', '5', 0, 0);")
+        # Invalid keyspace and table
+        session.execute("INSERT INTO size_estimates (keyspace_name, 
table_name, range_start, range_end, mean_partition_size, partitions_count) 
VALUES ('bad_keyspace', 'bad_table', '-5', '5', 0, 0);")
+        node.nodetool('refreshsizeestimates')
+        assert_none(session, "SELECT * FROM size_estimates WHERE 
keyspace_name='system_auth' AND table_name='bad_table'")
+        assert_none(session, "SELECT * FROM size_estimates WHERE 
keyspace_name='bad_keyspace'")
+
     @since('4.0')
     def test_set_get_concurrent_view_builders(self):
         """
diff --git a/schema_test.py b/schema_test.py
index 8aaea3d..6c9f8a1 100644
--- a/schema_test.py
+++ b/schema_test.py
@@ -4,8 +4,8 @@ import logging
 
 from cassandra.concurrent import execute_concurrent_with_args
 
-from tools.assertions import assert_invalid, assert_all, assert_one
-from dtest import Tester, create_ks
+from tools.assertions import assert_invalid, assert_all, assert_one, 
assert_none, assert_some
+from dtest import Tester, create_ks, create_cf
 
 since = pytest.mark.since
 logger = logging.getLogger(__name__)
@@ -176,6 +176,63 @@ class TestSchema(Tester):
         session.execute("USE ks")
         assert_all(session, "SELECT * FROM ts", [[1, 1, 'v1'], [1, 2, 'v2'], 
[2, 1, 'v3']])
 
+    @since('3.0')
+    def drop_table_reflected_in_size_estimates_test(self):
+        """
+        A dropped table should result in its entries being removed from size 
estimates, on both
+        nodes that are up and down at the time of the drop.
+
+        @jira_ticket CASSANDRA-14905
+        """
+        cluster = self.cluster
+        cluster.populate(2).start()
+        node1, node2 = cluster.nodelist()
+        session = self.patient_exclusive_cql_connection(node1)
+        create_ks(session, 'ks1', 2)
+        create_ks(session, 'ks2', 2)
+        create_cf(session, 'ks1.cf1', columns={'c1': 'text', 'c2': 'text'})
+        create_cf(session, 'ks2.cf1', columns={'c1': 'text', 'c2': 'text'})
+        create_cf(session, 'ks2.cf2', columns={'c1': 'text', 'c2': 'text'})
+
+        node1.nodetool('refreshsizeestimates')
+        node2.nodetool('refreshsizeestimates')
+        node2.stop()
+        session.execute('DROP TABLE ks2.cf1')
+        session.execute('DROP KEYSPACE ks1')
+        node2.start(wait_for_binary_proto=True)
+        session2 = self.patient_exclusive_cql_connection(node2)
+
+        session.cluster.control_connection.wait_for_schema_agreement()
+
+        assert_none(session, "SELECT * FROM system.size_estimates WHERE 
keyspace_name='ks1'")
+        assert_none(session, "SELECT * FROM system.size_estimates WHERE 
keyspace_name='ks2' AND table_name='cf1'")
+        assert_some(session, "SELECT * FROM system.size_estimates WHERE 
keyspace_name='ks2' AND table_name='cf2'")
+        assert_none(session2, "SELECT * FROM system.size_estimates WHERE 
keyspace_name='ks1'")
+        assert_none(session2, "SELECT * FROM system.size_estimates WHERE 
keyspace_name='ks2' AND table_name='cf1'")
+        assert_some(session, "SELECT * FROM system.size_estimates WHERE 
keyspace_name='ks2' AND table_name='cf2'")
+
+    @since('3.0')
+    def invalid_entries_removed_from_size_estimates_on_restart_test(self):
+        """
+        Entries for dropped tables/keyspaces should be cleared from 
size_estimates on restart.
+
+        @jira_ticket CASSANDRA-14905
+        """
+        cluster = self.cluster
+        cluster.populate(1).start()
+        node = cluster.nodelist()[0]
+        session = self.patient_cql_connection(node)
+        session.execute("USE system;")
+        session.execute("INSERT INTO size_estimates (keyspace_name, 
table_name, range_start, range_end, mean_partition_size, partitions_count) 
VALUES ( 'system_auth', 'bad_table', '-5', '5', 0, 0);")
+        # Invalid keyspace and table
+        session.execute("INSERT INTO size_estimates (keyspace_name, 
table_name, range_start, range_end, mean_partition_size, partitions_count) 
VALUES ( 'bad_keyspace', 'bad_table', '-5', '5', 0, 0);")
+        node.stop()
+        node.start()
+        session = self.patient_cql_connection(node)
+        assert_none(session, "SELECT * FROM system.size_estimates WHERE 
keyspace_name='system_auth' AND table_name='bad_table'")
+        assert_none(session, "SELECT * FROM system.size_estimates WHERE 
keyspace_name='bad_keyspace'")
+
+
     def prepare(self):
         cluster = self.cluster
         cluster.populate(1).start()
diff --git a/tools/assertions.py b/tools/assertions.py
index bce9b8a..d91e6fd 100644
--- a/tools/assertions.py
+++ b/tools/assertions.py
@@ -8,8 +8,8 @@ from cassandra.query import SimpleStatement
 
 
 """
-The assertion methods in this file are used to structure, execute, and test 
different queries and scenarios. 
-Use these anytime you are trying to check the content of a table, the row 
count of a table, if a query should 
+The assertion methods in this file are used to structure, execute, and test 
different queries and scenarios.
+Use these anytime you are trying to check the content of a table, the row 
count of a table, if a query should
 raise an exception, etc. These methods handle error messaging well, and will 
help discovering and treating bugs.
 
 An example:
@@ -149,6 +149,21 @@ def assert_none(session, query, cl=None):
     assert list_res == [], "Expected nothing from {}, but got 
{}".format(query, list_res)
 
 
+def assert_some(session, query, cl=None, execution_profile=None):
+    """
+    Assert query returns something
+    @param session Session to use
+    @param query Query to run
+    @param cl Optional Consistency Level setting. Default ONE
+     Examples:
+    assert_some(self.session1, "SELECT * FROM test where key=2;")
+    assert_some(cursor, "SELECT * FROM test WHERE k=2", 
cl=ConsistencyLevel.SERIAL)
+    """
+    res = _execute(session, query, cl=cl, execution_profile=execution_profile)
+    list_res = _rows_to_list(res)
+    assert list_res != [], "Expected something from {}, but got 
{}".format(query, list_res)
+
+
 def assert_all(session, query, expected, cl=None, ignore_order=False, 
timeout=None):
     """
     Assert query returns all expected items optionally in the correct order


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

Reply via email to