Add test for CASSANDRA-13043

Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/db1d058a
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/db1d058a
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/db1d058a

Branch: refs/heads/master
Commit: db1d058af51eafa36151a9eb818f5196bc632767
Parents: 163f82c
Author: Stefano Ortolani <ortol...@lastline.com>
Authored: Thu Aug 31 17:25:15 2017 +0100
Committer: Aleksey Yeschenko <alek...@yeschenko.com>
Committed: Thu Sep 21 12:10:17 2017 +0100

----------------------------------------------------------------------
 byteman/election_counter_leader_favor_node2.btm | 14 +++++++
 byteman/gossip_alive_callback_sleep.btm         | 13 ++++++
 counter_tests.py                                | 42 ++++++++++++++++++++
 3 files changed, 69 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/db1d058a/byteman/election_counter_leader_favor_node2.btm
----------------------------------------------------------------------
diff --git a/byteman/election_counter_leader_favor_node2.btm 
b/byteman/election_counter_leader_favor_node2.btm
new file mode 100644
index 0000000..f3d1ac3
--- /dev/null
+++ b/byteman/election_counter_leader_favor_node2.btm
@@ -0,0 +1,14 @@
+#
+# Cheat during the leader election for a counter mutation and favour node 2, 
127.0.0.2
+#
+# Note that this happens only if the node is known to be available.
+#
+RULE election counter leader cheat
+CLASS org.apache.cassandra.service.StorageProxy
+METHOD findSuitableEndpoint
+AT EXIT
+BIND isthere:boolean = 
$localEndpoints.contains(java.net.InetAddress.getByName("127.0.0.2"));
+if isthere
+DO
+    return java.net.InetAddress.getByName("127.0.0.2");
+ENDRULE

http://git-wip-us.apache.org/repos/asf/cassandra/blob/db1d058a/byteman/gossip_alive_callback_sleep.btm
----------------------------------------------------------------------
diff --git a/byteman/gossip_alive_callback_sleep.btm 
b/byteman/gossip_alive_callback_sleep.btm
new file mode 100644
index 0000000..2621b74
--- /dev/null
+++ b/byteman/gossip_alive_callback_sleep.btm
@@ -0,0 +1,13 @@
+#
+# Slow down how fast a node builds a view on the cluster by postponing when 
gossip settles.
+#
+# Note that this happens only if the node is known to be available.
+#
+RULE slow down falure detector
+CLASS org.apache.cassandra.gms.Gossiper
+METHOD realMarkAlive
+AT ENTRY
+IF TRUE
+DO
+   Thread.sleep(2000);
+ENDRULE
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/db1d058a/counter_tests.py
----------------------------------------------------------------------
diff --git a/counter_tests.py b/counter_tests.py
index c377060..da2ed09 100644
--- a/counter_tests.py
+++ b/counter_tests.py
@@ -74,6 +74,48 @@ class TestCounters(Tester):
         session = self.patient_cql_connection(node1, 
consistency_level=ConsistencyLevel.ALL)
         assert_one(session, "SELECT COUNT(*) FROM test.test", [1000])
 
+    def counter_leader_with_partial_view_test(self):
+        """
+        Test leader election with a starting node.
+
+        Testing that nodes do not elect as mutation leader a node with a 
partial view on the cluster.
+        Note that byteman rules can be syntax checked via the following 
command:
+            sh ./bin/bytemancheck.sh -cp 
~/path_to/apache-cassandra-3.0.14-SNAPSHOT.jar ~/path_to/rule.btm
+
+        @jira_ticket CASSANDRA-13043
+        """
+        cluster = self.cluster
+
+        cluster.populate(3, use_vnodes=True, install_byteman=True)
+        nodes = cluster.nodelist()
+        # Have node 1 and 3 cheat a bit during the leader election for a 
counter mutation; note that cheating
+        # takes place iff there is an actual chance for node 2 to be picked.
+        
nodes[0].update_startup_byteman_script('./byteman/election_counter_leader_favor_node2.btm')
+        
nodes[2].update_startup_byteman_script('./byteman/election_counter_leader_favor_node2.btm')
+        cluster.start(wait_for_binary_proto=True)
+        session = self.patient_cql_connection(nodes[0])
+        create_ks(session, 'ks', 3)
+        create_cf(session, 'cf', validation="CounterColumnType", columns={'c': 
'counter'})
+
+        # Now stop the node and restart but first install a rule to slow down 
how fast node 2 will update the list
+        # nodes that are alive
+        nodes[1].stop(wait=True, wait_other_notice=False)
+        
nodes[1].update_startup_byteman_script('./byteman/gossip_alive_callback_sleep.btm')
+        nodes[1].start(no_wait=True, wait_other_notice=False)
+
+        # Until node 2 is fully alive try to force other nodes to pick him as 
mutation leader.
+        # If CASSANDRA-13043 is fixed, they will not. Otherwise they will do, 
but since we are slowing down how
+        # fast node 2 updates the list of nodes that are alive, it will just 
have a partial view on the cluster
+        # and thus will raise an 'UnavailableException' exception.
+        nb_attempts = 50000
+        for i in xrange(0, nb_attempts):
+            # Change the name of the counter for the sake of randomization
+            q = SimpleStatement(
+                query_string="UPDATE ks.cf SET c = c + 1 WHERE key = 
'counter_%d'" % i,
+                consistency_level=ConsistencyLevel.QUORUM
+            )
+            session.execute(q)
+
     def simple_increment_test(self):
         """ Simple incrementation test (Created for #3465, that wasn't a bug) 
"""
         cluster = self.cluster


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

Reply via email to