blob: 86627ab6fc32a661f89cb87c25368d39d05eaa49 [file] [log] [blame]
import time
from cassandra import ConsistencyLevel
from cassandra.query import SimpleStatement
from dtest import Tester
from tools.decorators import no_vnodes, since
@since('4.0')
class PreviewRepairTest(Tester):
def assert_no_repair_history(self, session):
rows = session.execute("select * from system_distributed.repair_history")
self.assertEqual(rows.current_rows, [])
rows = session.execute("select * from system_distributed.parent_repair_history")
self.assertEqual(rows.current_rows, [])
@no_vnodes()
def preview_test(self):
""" Test that preview correctly detects out of sync data """
cluster = self.cluster
cluster.set_configuration_options(values={'hinted_handoff_enabled': False, 'commitlog_sync_period_in_ms': 500})
cluster.populate(3).start()
node1, node2, node3 = cluster.nodelist()
session = self.patient_exclusive_cql_connection(node3)
session.execute("CREATE KEYSPACE ks WITH REPLICATION={'class':'SimpleStrategy', 'replication_factor': 3}")
session.execute("CREATE TABLE ks.tbl (k INT PRIMARY KEY, v INT)")
# everything should be in sync
result = node1.repair(options=['ks', '--preview'])
self.assertIn("Previewed data was in sync", result.stdout)
self.assert_no_repair_history(session)
# make data inconsistent between nodes
stmt = SimpleStatement("INSERT INTO ks.tbl (k,v) VALUES (%s, %s)")
stmt.consistency_level = ConsistencyLevel.ALL
for i in range(10):
session.execute(stmt, (i, i))
node3.flush()
time.sleep(1)
node3.stop(gently=False)
stmt.consistency_level = ConsistencyLevel.QUORUM
session = self.exclusive_cql_connection(node1)
for i in range(10):
session.execute(stmt, (i + 10, i + 10))
node1.flush()
time.sleep(1)
node1.stop(gently=False)
node3.start(wait_other_notice=True, wait_for_binary_proto=True)
session = self.exclusive_cql_connection(node2)
for i in range(10):
session.execute(stmt, (i + 20, i + 20))
node1.start(wait_other_notice=True, wait_for_binary_proto=True)
# data should not be in sync for full and unrepaired previews
result = node1.repair(options=['ks', '--preview'])
self.assertIn("Total estimated streaming", result.stdout)
self.assertNotIn("Previewed data was in sync", result.stdout)
result = node1.repair(options=['ks', '--preview', '--full'])
self.assertIn("Total estimated streaming", result.stdout)
self.assertNotIn("Previewed data was in sync", result.stdout)
# repaired data should be in sync anyway
result = node1.repair(options=['ks', '--validate'])
self.assertIn("Repaired data is in sync", result.stdout)
self.assert_no_repair_history(session)
# repair the data...
node1.repair(options=['ks'])
for node in cluster.nodelist():
node.nodetool('compact ks tbl')
# ...and everything should be in sync
result = node1.repair(options=['ks', '--preview'])
self.assertIn("Previewed data was in sync", result.stdout)
result = node1.repair(options=['ks', '--preview', '--full'])
self.assertIn("Previewed data was in sync", result.stdout)
result = node1.repair(options=['ks', '--validate'])
self.assertIn("Repaired data is in sync", result.stdout)