| import logging |
| |
| import pytest |
| |
| from dtest import Tester |
| from tools.misc import new_node |
| |
| since = pytest.mark.since |
| logger = logging.getLogger(__name__) |
| |
| class TestGossip(Tester): |
| """ |
| This test suite looks at how gossip information is distributed within |
| a cluster under various scenarios that alter gossip state. |
| """ |
| @pytest.mark.no_vnodes |
| def test_assassination_of_unknown_node(self): |
| """ |
| @jira_ticket CASSANDRA-16588 |
| Test that a non-seed node can come back online after assassinating an |
| unknown node. |
| """ |
| cluster = self.cluster |
| |
| # Create a 5-node cluster |
| cluster.populate(5) |
| node1 = cluster.nodelist()[0] |
| node3 = cluster.nodelist()[2] |
| |
| self.cluster.set_configuration_options({ |
| 'seed_provider': [{'class_name': 'org.apache.cassandra.locator.SimpleSeedProvider', |
| 'parameters': [{'seeds': node1.address()}] |
| }] |
| }) |
| |
| cluster.start() |
| |
| logger.debug("Shutting down node {}".format(node3.address())) |
| node3.stop() |
| |
| logger.debug("Assassinating unknown node 11.1.1.1") |
| out, err, _ = node1.nodetool("assassinate 11.1.1.1") |
| assert len(err.strip()) <= 0, "nodetool command failed: {}".format(err) |
| |
| logger.debug("Starting node {}".format(node3.address())) |
| node3.start() |
| |
| def test_assassinate_valid_node(self): |
| """ |
| @jira_ticket CASSANDRA-16588 |
| Test that after taking two non-seed nodes down and assassinating |
| one of them, the other can come back up. |
| """ |
| cluster = self.cluster |
| |
| cluster.populate(5).start() |
| node1 = cluster.nodelist()[0] |
| node3 = cluster.nodelist()[2] |
| |
| self.cluster.set_configuration_options({ |
| 'seed_provider': [{'class_name': 'org.apache.cassandra.locator.SimpleSeedProvider', |
| 'parameters': [{'seeds': node1.address()}] |
| }] |
| }) |
| |
| non_seed_nodes = cluster.nodelist()[-2:] |
| for node in non_seed_nodes: |
| node.stop() |
| |
| assassination_target = non_seed_nodes[0] |
| logger.debug("Assassinating non-seed node {}".format(assassination_target.address())) |
| out, err, _ = node1.nodetool("assassinate {}".format(assassination_target.address())) |
| assert len(err.strip()) <= 0, "nodetool command failed: {}".format(err) |
| |
| logger.debug("Starting non-seed nodes") |
| for node in non_seed_nodes: |
| node.start() |
| |
| def _cluster_create_node(self, num): |
| address = '127.0.0.%d' % num |
| return self.cluster.create_node("node%s" % num, False, None, |
| (address, 7000 + num), |
| str(7100 + num), str(2000 + num), None, |
| binary_interface=(address, 9042)) |
| |
| def _start_nodes_in_parallel(self, nodelist): |
| for node in nodelist: |
| node.start(no_wait=True) |
| |
| # Wait 30 seconds for nodes to come up |
| for _ in range(30): |
| if [n for n in nodelist if n.is_running()] == nodelist: |
| break |
| time.sleep(1) |
| |
| for node in nodelist: |
| assert node.is_running() |
| |
| def _create_2dc_cluster(self): |
| cluster = self.cluster |
| cluster.set_configuration_options(values={'endpoint_snitch': 'org.apache.cassandra.locator.PropertyFileSnitch'}) |
| |
| # Add dc1 nodes |
| node1 = self._cluster_create_node(1) |
| cluster.add(node1, True, data_center='dc1') |
| node1.start() |
| node2 = self._cluster_create_node(2) |
| cluster.add(node2, False, data_center='dc1') |
| node2.start() |
| |
| # Add dc2 nodes |
| node3 = self._cluster_create_node(3) |
| cluster.add(node3, True, data_center='dc2') |
| node3.start() |
| node4 = self._cluster_create_node(4) |
| cluster.add(node4, False, data_center='dc2') |
| node4.start() |
| |
| # Stop cluster |
| for node in cluster.nodelist(): |
| node.stop() |
| |
| return node1, node2, node3, node4 |
| |
| @since('4.0') |
| def test_2dc_parallel_startup(self): |
| """ |
| @jira_ticket CASSANDRA-16588 |
| Given a 2 DC cluster, start all seeds node in parallel followed by |
| all non-seed nodes in parallel. |
| """ |
| node1, node2, node3, node4 = self._create_2dc_cluster() |
| |
| # Start seeds in parallel |
| self._start_nodes_in_parallel([node1, node3]) |
| |
| # Start non-seeds in parallel |
| self._start_nodes_in_parallel([node2, node4]) |
| |
| @since('4.0') |
| def test_2dc_parallel_startup_one_seed(self): |
| """ |
| @jira_ticket CASSANDRA-16588 |
| Given a 2 DC cluster, start one seed node followed by all non-seed |
| nodes in parallel. |
| """ |
| node1, node2, node3, node4 = self._create_2dc_cluster() |
| |
| # Start one seed (of two) |
| self._start_nodes_in_parallel([node1]) |
| |
| # Start non-seeds in parallel |
| self._start_nodes_in_parallel([node2, node4]) |