You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by aw...@apache.org on 2018/01/29 21:10:22 UTC
[19/36] cassandra-dtest git commit: Migrate dtests to use pytest and
python3
http://git-wip-us.apache.org/repos/asf/cassandra-dtest/blob/49b2dda4/replication_test.py
----------------------------------------------------------------------
diff --git a/replication_test.py b/replication_test.py
index edc6fc0..8c29074 100644
--- a/replication_test.py
+++ b/replication_test.py
@@ -1,14 +1,18 @@
import os
import re
import time
+import pytest
+import logging
+
from collections import defaultdict
from cassandra import ConsistencyLevel
from cassandra.query import SimpleStatement
-from nose.plugins.attrib import attr
-from dtest import PRINT_DEBUG, DtestTimeoutError, Tester, debug, create_ks
-from tools.decorators import no_vnodes, since
+from dtest import DtestTimeoutError, Tester, create_ks
+
+since = pytest.mark.since
+logger = logging.getLogger(__name__)
TRACE_DETERMINE_REPLICAS = re.compile('Determining replicas for mutation')
TRACE_SEND_MESSAGE = re.compile('Sending (?:MUTATION|REQUEST_RESPONSE) message to /([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)')
@@ -73,8 +77,8 @@ def block_on_trace(session):
raise DtestTimeoutError()
-@no_vnodes()
-class ReplicationTest(Tester):
+@pytest.mark.no_vnodes
+class TestReplication(Tester):
"""
This test suite looks at how data is replicated across a cluster
and who the coordinator, replicas and forwarders involved are.
@@ -176,7 +180,7 @@ class ReplicationTest(Tester):
elif strategy == 'NetworkTopologyStrategy':
# NetworkTopologyStrategy can be broken down into multiple
# SimpleStrategies, just once per datacenter:
- for dc, rf in replication_factor.items():
+ for dc, rf in list(replication_factor.items()):
dc_nodes = [n for n in nodes if n.data_center == dc]
replicas.extend(self.get_replicas_for_token(
token, rf, nodes=dc_nodes))
@@ -190,13 +194,13 @@ class ReplicationTest(Tester):
"""
Pretty print a trace
"""
- if PRINT_DEBUG:
- print("-" * 40)
+ if logging.root.level == logging.DEBUG:
+ print(("-" * 40))
for t in trace.events:
- print("%s\t%s\t%s\t%s" % (t.source, t.source_elapsed, t.description, t.thread_name))
- print("-" * 40)
+ print(("%s\t%s\t%s\t%s" % (t.source, t.source_elapsed, t.description, t.thread_name)))
+ print(("-" * 40))
- def simple_test(self):
+ def test_simple(self):
"""
Test the SimpleStrategy on a 3 node cluster
"""
@@ -209,8 +213,8 @@ class ReplicationTest(Tester):
create_ks(session, 'test', replication_factor)
session.execute('CREATE TABLE test.test (id int PRIMARY KEY, value text)', trace=False)
- for key, token in murmur3_hashes.items():
- debug('murmur3 hash key={key},token={token}'.format(key=key, token=token))
+ for key, token in list(murmur3_hashes.items()):
+ logger.debug('murmur3 hash key={key},token={token}'.format(key=key, token=token))
query = SimpleStatement("INSERT INTO test (id, value) VALUES ({}, 'asdf')".format(key), consistency_level=ConsistencyLevel.ALL)
future = session.execute_async(query, trace=True)
future.result()
@@ -222,17 +226,17 @@ class ReplicationTest(Tester):
stats = self.get_replicas_from_trace(trace)
replicas_should_be = set(self.get_replicas_for_token(
token, replication_factor))
- debug('\nreplicas should be: %s' % replicas_should_be)
- debug('replicas were: %s' % stats['replicas'])
+ logger.debug('\nreplicas should be: %s' % replicas_should_be)
+ logger.debug('replicas were: %s' % stats['replicas'])
# Make sure the correct nodes are replicas:
- self.assertEqual(stats['replicas'], replicas_should_be)
+ assert stats['replicas'] == replicas_should_be
# Make sure that each replica node was contacted and
# acknowledged the write:
- self.assertEqual(stats['nodes_sent_write'], stats['nodes_responded_write'])
+ assert stats['nodes_sent_write'] == stats['nodes_responded_write']
- @attr("resource-intensive")
- def network_topology_test(self):
+ @pytest.mark.resource_intensive
+ def test_network_topology(self):
"""
Test the NetworkTopologyStrategy on a 2DC 3:3 node cluster
"""
@@ -248,7 +252,7 @@ class ReplicationTest(Tester):
forwarders_used = set()
- for key, token in murmur3_hashes.items():
+ for key, token in list(murmur3_hashes.items()):
query = SimpleStatement("INSERT INTO test (id, value) VALUES ({}, 'asdf')".format(key), consistency_level=ConsistencyLevel.ALL)
future = session.execute_async(query, trace=True)
future.result()
@@ -260,9 +264,9 @@ class ReplicationTest(Tester):
stats = self.get_replicas_from_trace(trace)
replicas_should_be = set(self.get_replicas_for_token(
token, replication_factor, strategy='NetworkTopologyStrategy'))
- debug('Current token is %s' % token)
- debug('\nreplicas should be: %s' % replicas_should_be)
- debug('replicas were: %s' % stats['replicas'])
+ logger.debug('Current token is %s' % token)
+ logger.debug('\nreplicas should be: %s' % replicas_should_be)
+ logger.debug('replicas were: %s' % stats['replicas'])
# Make sure the coordinator only talked to a single node in
# the second datacenter - CASSANDRA-5632:
@@ -270,27 +274,27 @@ class ReplicationTest(Tester):
for node_contacted in stats['nodes_contacted'][node1.address()]:
if ip_nodes[node_contacted].data_center != node1.data_center:
num_in_other_dcs_contacted += 1
- self.assertEqual(num_in_other_dcs_contacted, 1)
+ assert num_in_other_dcs_contacted == 1
# Record the forwarder used for each INSERT:
forwarders_used = forwarders_used.union(stats['forwarders'])
try:
# Make sure the correct nodes are replicas:
- self.assertEqual(stats['replicas'], replicas_should_be)
+ assert stats['replicas'] == replicas_should_be
# Make sure that each replica node was contacted and
# acknowledged the write:
- self.assertEqual(stats['nodes_sent_write'], stats['nodes_responded_write'])
+ assert stats['nodes_sent_write'] == stats['nodes_responded_write']
except AssertionError as e:
- debug("Failed on key %s and token %s." % (key, token))
+ logger.debug("Failed on key %s and token %s." % (key, token))
raise e
# Given a diverse enough keyset, each node in the second
# datacenter should get a chance to be a forwarder:
- self.assertEqual(len(forwarders_used), 3)
+ assert len(forwarders_used) == 3
-class SnitchConfigurationUpdateTest(Tester):
+class TestSnitchConfigurationUpdate(Tester):
"""
Test to reproduce CASSANDRA-10238, wherein changing snitch properties to change racks without a restart
could violate RF contract.
@@ -299,27 +303,31 @@ class SnitchConfigurationUpdateTest(Tester):
which nodes should be shutdown in order to have the rack changed.
"""
- ignore_log_patterns = ["Fatal exception during initialization",
- "Cannot start node if snitch's rack(.*) differs from previous rack(.*)",
- "Cannot update data center or rack"]
+ @pytest.fixture(autouse=True)
+ def fixture_add_additional_log_patterns(self, fixture_dtest_setup):
+ fixture_dtest_setup.ignore_log_patterns = (
+ "Fatal exception during initialization",
+ "Cannot start node if snitch's rack(.*) differs from previous rack(.*)",
+ "Cannot update data center or rack"
+ )
def check_endpoint_count(self, ks, table, nodes, rf):
"""
Check a dummy key expecting it to have replication factor as the sum of rf on all dcs.
"""
- expected_count = sum([int(r) for d, r in rf.iteritems() if d != 'class'])
+ expected_count = sum([int(r) for d, r in rf.items() if d != 'class'])
for node in nodes:
cmd = "getendpoints {} {} dummy".format(ks, table)
out, err, _ = node.nodetool(cmd)
if len(err.strip()) > 0:
- debug("Error running 'nodetool {}': {}".format(cmd, err))
+ logger.debug("Error running 'nodetool {}': {}".format(cmd, err))
- debug("Endpoints for node {}, expected count is {}".format(node.address(), expected_count))
- debug(out)
+ logger.debug("Endpoints for node {}, expected count is {}".format(node.address(), expected_count))
+ logger.debug(out)
ips_found = re.findall('(\d+\.\d+\.\d+\.\d+)', out)
- self.assertEqual(len(ips_found), expected_count, "wrong number of endpoints found ({}), should be: {}".format(len(ips_found), expected_count))
+ assert len(ips_found) == expected_count, "wrong number of endpoints found ({}), should be: {}".format(len(ips_found), expected_count)
def wait_for_nodes_on_racks(self, nodes, expected_racks):
"""
@@ -331,9 +339,9 @@ class SnitchConfigurationUpdateTest(Tester):
while time.time() < wait_expire:
out, err, _ = node.nodetool("status")
- debug(out)
+ logger.debug(out)
if len(err.strip()) > 0:
- debug("Error trying to run nodetool status: {}".format(err))
+ logger.debug("Error trying to run nodetool status: {}".format(err))
racks = []
for line in out.split(os.linesep):
@@ -343,10 +351,10 @@ class SnitchConfigurationUpdateTest(Tester):
if racks == expected_racks:
# great, the topology change is propagated
- debug("Topology change detected on node {}".format(i))
+ logger.debug("Topology change detected on node {}".format(i))
break
else:
- debug("Waiting for topology change on node {}".format(i))
+ logger.debug("Waiting for topology change on node {}".format(i))
time.sleep(5)
else:
raise RuntimeError("Ran out of time waiting for topology to change on node {}".format(i))
@@ -383,7 +391,7 @@ class SnitchConfigurationUpdateTest(Tester):
final_racks=["rack0", "rack1", "rack2"],
nodes_to_shutdown=[0, 2])
- @attr("resource-intensive")
+ @pytest.mark.resource_intensive
def test_rf_collapse_gossiping_property_file_snitch_multi_dc(self):
"""
@jira_ticket CASSANDRA-10238
@@ -400,7 +408,7 @@ class SnitchConfigurationUpdateTest(Tester):
final_racks=["rack1", "rack1", "rack1", "rack1", "rack1", "rack1"],
nodes_to_shutdown=[0, 2, 3, 5])
- @attr("resource-intensive")
+ @pytest.mark.resource_intensive
def test_rf_expand_gossiping_property_file_snitch_multi_dc(self):
"""
@jira_ticket CASSANDRA-10238
@@ -537,7 +545,7 @@ class SnitchConfigurationUpdateTest(Tester):
session = self.patient_cql_connection(cluster.nodelist()[0])
- options = (', ').join(['\'{}\': {}'.format(d, r) for d, r in rf.iteritems()])
+ options = (', ').join(['\'{}\': {}'.format(d, r) for d, r in rf.items()])
session.execute("CREATE KEYSPACE testing WITH replication = {{{}}}".format(options))
session.execute("CREATE TABLE testing.rf_test (key text PRIMARY KEY, value text)")
@@ -548,10 +556,10 @@ class SnitchConfigurationUpdateTest(Tester):
for i in nodes_to_shutdown:
node = cluster.nodelist()[i]
- debug("Shutting down node {}".format(node.address()))
+ logger.debug("Shutting down node {}".format(node.address()))
node.stop(wait_other_notice=True)
- debug("Updating snitch file")
+ logger.debug("Updating snitch file")
for i, node in enumerate(cluster.nodelist()):
with open(os.path.join(node.get_conf_dir(), snitch_config_file), 'w') as topo_file:
for line in snitch_lines_after(i, node):
@@ -559,12 +567,12 @@ class SnitchConfigurationUpdateTest(Tester):
# wait until the config is reloaded before we restart the nodes, the default check period is
# 5 seconds so we wait for 10 seconds to be sure
- debug("Waiting 10 seconds to make sure snitch file is reloaded...")
+ logger.debug("Waiting 10 seconds to make sure snitch file is reloaded...")
time.sleep(10)
for i in nodes_to_shutdown:
node = cluster.nodelist()[i]
- debug("Restarting node {}".format(node.address()))
+ logger.debug("Restarting node {}".format(node.address()))
# Since CASSANDRA-10242 it is no longer
# possible to start a node with a different rack unless we specify -Dcassandra.ignore_rack and since
# CASSANDRA-9474 it is no longer possible to start a node with a different dc unless we specify
@@ -594,24 +602,24 @@ class SnitchConfigurationUpdateTest(Tester):
for line in ["dc={}".format(node1.data_center), "rack=rack1"]:
topo_file.write(line + os.linesep)
- debug("Starting node {} with rack1".format(node1.address()))
+ logger.debug("Starting node {} with rack1".format(node1.address()))
node1.start(wait_for_binary_proto=True)
- debug("Shutting down node {}".format(node1.address()))
+ logger.debug("Shutting down node {}".format(node1.address()))
node1.stop(wait_other_notice=True)
- debug("Updating snitch file with rack2")
+ logger.debug("Updating snitch file with rack2")
for node in cluster.nodelist():
with open(os.path.join(node.get_conf_dir(), 'cassandra-rackdc.properties'), 'w') as topo_file:
for line in ["dc={}".format(node.data_center), "rack=rack2"]:
topo_file.write(line + os.linesep)
- debug("Restarting node {} with rack2".format(node1.address()))
+ logger.debug("Restarting node {} with rack2".format(node1.address()))
mark = node1.mark_log()
node1.start()
# check node not running
- debug("Waiting for error message in log file")
+ logger.debug("Waiting for error message in log file")
if cluster.version() >= '2.2':
node1.watch_log_for("Cannot start node if snitch's rack(.*) differs from previous rack(.*)",
@@ -696,7 +704,7 @@ class SnitchConfigurationUpdateTest(Tester):
marks = [node.mark_log() for node in cluster.nodelist()]
- debug("Updating snitch file")
+ logger.debug("Updating snitch file")
for node in cluster.nodelist():
with open(os.path.join(node.get_conf_dir(), snitch_config_file), 'w') as topo_file:
for line in snitch_lines_after:
@@ -704,7 +712,7 @@ class SnitchConfigurationUpdateTest(Tester):
# wait until the config is reloaded, the default check period is
# 5 seconds so we wait for 10 seconds to be sure
- debug("Waiting 10 seconds to make sure snitch file is reloaded...")
+ logger.debug("Waiting 10 seconds to make sure snitch file is reloaded...")
time.sleep(10)
# check racks have not changed
@@ -723,7 +731,7 @@ class SnitchConfigurationUpdateTest(Tester):
"""
expected_error = (r"Cannot start node if snitch's data center (.*) differs from previous data center (.*)\. "
"Please fix the snitch configuration, decommission and rebootstrap this node or use the flag -Dcassandra.ignore_dc=true.")
- self.ignore_log_patterns = [expected_error]
+ self.fixture_dtest_setup.ignore_log_patterns = [expected_error]
cluster = self.cluster
cluster.populate(1)
@@ -744,4 +752,4 @@ class SnitchConfigurationUpdateTest(Tester):
mark = node.mark_log()
node.start()
- node.watch_log_for(expected_error, from_mark=mark, timeout=10)
+ node.watch_log_for(expected_error, from_mark=mark, timeout=120)
http://git-wip-us.apache.org/repos/asf/cassandra-dtest/blob/49b2dda4/requirements.txt
----------------------------------------------------------------------
diff --git a/requirements.txt b/requirements.txt
index bf46e38..388a8a9 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,21 +1,18 @@
-# See python driver docs: futures and six have to be installed before
-# cythonizing the driver, perhaps only on old pips.
-# http://datastax.github.io/python-driver/installation.html#cython-based-extensions
-futures
-six
-e git+https://github.com/datastax/python-driver.git@cassandra-test#egg=cassandra-driver
# Used ccm version is tracked by cassandra-test branch in ccm repo. Please create a PR there for fixes or upgrades to new releases.
--e git+https://github.com/pcmanus/ccm.git@cassandra-test#egg=ccm
-cql
+-e git+https://github.com/riptano/ccm.git@cassandra-test#egg=ccm
+cqlsh
decorator
docopt
enum34
flaky
mock
-nose
-nose-test-select
+pytest
+pytest-timeout
parse
pycodestyle
psutil
-pycassa
-thrift==0.9.3
+thrift==0.10.0
+netifaces
+beautifulsoup4
+lxml
http://git-wip-us.apache.org/repos/asf/cassandra-dtest/blob/49b2dda4/run_dtests.py
----------------------------------------------------------------------
diff --git a/run_dtests.py b/run_dtests.py
index e7165af..198cde2 100755
--- a/run_dtests.py
+++ b/run_dtests.py
@@ -1,264 +1,280 @@
#!/usr/bin/env python
"""
-Usage: run_dtests.py [--nose-options NOSE_OPTIONS] [TESTS...] [--vnodes VNODES_OPTIONS...]
- [--runner-debug | --runner-quiet] [--dry-run]
-
-nosetests options:
- --nose-options NOSE_OPTIONS specify options to pass to `nosetests`.
- TESTS space-separated list of tests to pass to `nosetests`
-
-script configuration options:
- --runner-debug -d print debug statements in this script
- --runner-quiet -q quiet all output from this script
-
-cluster configuration options:
- --vnodes VNODES_OPTIONS... specify whether to run with or without vnodes.
- valid values: 'true' and 'false'
-
-example:
- The following command will execute nosetests with the '-v' (verbose) option, vnodes disabled, and run a single test:
- ./run_dtests.py --nose-options -v --vnodes false repair_tests/repair_test.py:TestRepair.token_range_repair_test_with_cf
-
+usage: run_dtests.py [-h] [--use-vnodes] [--use-off-heap-memtables] [--num-tokens NUM_TOKENS] [--data-dir-count-per-instance DATA_DIR_COUNT_PER_INSTANCE] [--force-resource-intensive-tests]
+ [--skip-resource-intensive-tests] [--cassandra-dir CASSANDRA_DIR] [--cassandra-version CASSANDRA_VERSION] [--delete-logs] [--execute-upgrade-tests] [--disable-active-log-watching]
+ [--keep-test-dir] [--enable-jacoco-code-coverage] [--dtest-enable-debug-logging] [--dtest-print-tests-only] [--dtest-print-tests-output DTEST_PRINT_TESTS_OUTPUT]
+ [--pytest-options PYTEST_OPTIONS] [--dtest-tests DTEST_TESTS]
+
+optional arguments:
+ -h, --help show this help message and exit
+ --use-vnodes Determines wither or not to setup clusters using vnodes for tests (default: False)
+ --use-off-heap-memtables Enable Off Heap Memtables when creating test clusters for tests (default: False)
+ --num-tokens NUM_TOKENS Number of tokens to set num_tokens yaml setting to when creating instances with vnodes enabled (default: 256)
+ --data-dir-count-per-instance DATA_DIR_COUNT_PER_INSTANCE Control the number of data directories to create per instance (default: 3)
+ --force-resource-intensive-tests Forces the execution of tests marked as resource_intensive (default: False)
+ --skip-resource-intensive-tests Skip all tests marked as resource_intensive (default: False)
+ --cassandra-dir CASSANDRA_DIR
+ --cassandra-version CASSANDRA_VERSION
+ --delete-logs
+ --execute-upgrade-tests Execute Cassandra Upgrade Tests (e.g. tests annotated with the upgrade_test mark) (default: False)
+ --disable-active-log-watching Disable ccm active log watching, which will cause dtests to check for errors in the logs in a single operation instead of semi-realtime
+ processing by consuming ccm _log_error_handler callbacks (default: False)
+ --keep-test-dir Do not remove/cleanup the test ccm cluster directory and it's artifacts after the test completes (default: False)
+ --enable-jacoco-code-coverage Enable JaCoCo Code Coverage Support (default: False)
+ --dtest-enable-debug-logging Enable debug logging (for this script, pytest, and during execution of test functions) (default: False)
+ --dtest-print-tests-only Print list of all tests found eligible for execution given the provided options. (default: False)
+ --dtest-print-tests-output DTEST_PRINT_TESTS_OUTPUT Path to file where the output of --dtest-print-tests-only should be written to (default: False)
+ --pytest-options PYTEST_OPTIONS Additional command line arguments to proxy directly thru when invoking pytest. (default: None)
+ --dtest-tests DTEST_TESTS Comma separated list of test files, test classes, or test methods to execute. (default: None)
"""
-from __future__ import print_function
-
import subprocess
import sys
import os
-from collections import namedtuple
-from itertools import product
-from os import getcwd, environ
-from tempfile import NamedTemporaryFile
-
-from docopt import docopt
-
-from plugins.dtestconfig import GlobalConfigObject
-
-
-# Generate values in a matrix from these lists of values for each attribute
-# not defined in arguments to the runner script.
-default_config_matrix = GlobalConfigObject(
- vnodes=(True, False),
-)
-
+import re
+import logging
-def _noop(*args, **kwargs):
- pass
-
-
-class ValidationResult(namedtuple('_ValidationResult', ['serialized', 'error_messages'])):
- """
- A value to be returned from validation functions. If serialization works,
- return one with 'serialized' set, otherwise return a list of string on the
- 'error_messages' attribute.
- """
- __slots__ = ()
+from os import getcwd
+from tempfile import NamedTemporaryFile
+from bs4 import BeautifulSoup
- def __new__(cls, serialized=None, error_messages=None):
- if error_messages is None:
- error_messages = []
+from _pytest.config import Parser
+import argparse
- success_result = serialized is not None
- failure_result = bool(error_messages)
+from conftest import pytest_addoption
- if success_result + failure_result != 1:
- msg = ('attempted to instantiate a {cls_name} with serialized='
- '{serialized} and error_messages={error_messages}. {cls_name} '
- 'objects must be instantiated with either a serialized or '
- 'error_messages argument, but not both.')
- msg = msg.format(cls_name=cls.__name__,
- serialized=serialized,
- error_messages=error_messages)
- raise ValueError(msg)
+logger = logging.getLogger(__name__)
- return super(ValidationResult, cls).__new__(cls, serialized=serialized, error_messages=error_messages)
+class RunDTests():
+ def run(self, argv):
+ parser = argparse.ArgumentParser(formatter_class=lambda prog: argparse.ArgumentDefaultsHelpFormatter(prog,
+ max_help_position=100,
+ width=200))
-def _validate_and_serialize_vnodes(vnodes_value):
- """
- Validate the values received for vnodes configuration. Returns a
- ValidationResult.
+ # this is a bit ugly: all of our command line arguments are added and configured as part
+ # of pytest. however, we also have this wrapper script to make it easier for those who
+ # aren't comfortable calling pytest directly. To avoid duplicating code (e.g. have the options
+ # in two separate places) we directly use the pytest_addoption fixture from conftest.py. Unfortunately,
+ # pytest wraps ArgumentParser, so, first we add the options to a pytest Parser, and then we pull
+ # all of those custom options out and add them to the unwrapped ArgumentParser we want to use
+ # here inside of run_dtests.py.
+ #
+ # So NOTE: to add a command line argument, if you're trying to do so by adding it here, you're doing it wrong!
+ # add it to conftest.py:pytest_addoption
+ pytest_parser = Parser()
+ pytest_addoption(pytest_parser)
+
+ # add all of the options from the pytest Parser we created, and add them into our ArgumentParser instance
+ pytest_custom_opts = pytest_parser._anonymous
+ for opt in pytest_custom_opts.options:
+ parser.add_argument(opt._long_opts[0], action=opt._attrs['action'],
+ default=opt._attrs.get('default', None),
+ help=opt._attrs.get('help', None))
+
+ parser.add_argument("--dtest-enable-debug-logging", action="store_true", default=False,
+ help="Enable debug logging (for this script, pytest, and during execution "
+ "of test functions)")
+ parser.add_argument("--dtest-print-tests-only", action="store_true", default=False,
+ help="Print list of all tests found eligible for execution given the provided options.")
+ parser.add_argument("--dtest-print-tests-output", action="store", default=False,
+ help="Path to file where the output of --dtest-print-tests-only should be written to")
+ parser.add_argument("--pytest-options", action="store", default=None,
+ help="Additional command line arguments to proxy directly thru when invoking pytest.")
+ parser.add_argument("--dtest-tests", action="store", default=None,
+ help="Comma separated list of test files, test classes, or test methods to execute.")
+
+ args = parser.parse_args()
+
+ if not args.dtest_print_tests_only and args.cassandra_dir is None:
+ if args.cassandra_version is None:
+ raise Exception("Required dtest arguments were missing! You must provide either --cassandra-dir "
+ "or --cassandra-version. Refer to the documentation or invoke the help with --help.")
+
+ if args.dtest_enable_debug_logging:
+ logging.root.setLevel(logging.DEBUG)
+ logger.setLevel(logging.DEBUG)
+
+ # Get dictionaries corresponding to each point in the configuration matrix
+ # we want to run, then generate a config object for each of them.
+ logger.debug('Generating configurations from the following matrix:\n\t{}'.format(args))
+
+ args_to_invoke_pytest = []
+ if args.pytest_options:
+ for arg in args.pytest_options.split(" "):
+ args_to_invoke_pytest.append("'{the_arg}'".format(the_arg=arg))
+
+ for arg in argv:
+ if arg.startswith("--pytest-options") or arg.startswith("--dtest-"):
+ continue
+ args_to_invoke_pytest.append("'{the_arg}'".format(the_arg=arg))
+
+ if args.dtest_print_tests_only:
+ args_to_invoke_pytest.append("'--collect-only'")
+
+ if args.dtest_tests:
+ for test in args.dtest_tests.split(","):
+ args_to_invoke_pytest.append("'{test_name}'".format(test_name=test))
+
+ original_raw_cmd_args = ", ".join(args_to_invoke_pytest)
+
+ logger.debug("args to call with: [%s]" % original_raw_cmd_args)
+
+ # the original run_dtests.py script did it like this to hack around nosetest
+ # limitations -- i'm not sure if they still apply or not in a pytest world
+ # but for now just leaving it as is, because it does the job (although
+ # certainly is still pretty complicated code and has a hacky feeling)
+ to_execute = (
+ "import pytest\n" +
+ (
+ "pytest.main([{options}])\n").format(options=original_raw_cmd_args)
+ )
+ temp = NamedTemporaryFile(dir=getcwd())
+ logger.debug('Writing the following to {}:'.format(temp.name))
- If the values validate, return a ValidationResult with 'serialized' set to
- the equivalent of:
+ logger.debug('```\n{to_execute}```\n'.format(to_execute=to_execute))
+ temp.write(to_execute.encode("utf-8"))
+ temp.flush()
- tuple(set({'true': True, 'false':False}[v.lower()] for v in vnodes_value))
+ # We pass nose_argv as options to the python call to maintain
+ # compatibility with the nosetests command. Arguments passed in via the
+ # command line are treated one way, args passed in as
+ # nose.main(argv=...) are treated another. Compare with the options
+ # -xsv for an example.
+ cmd_list = [sys.executable, temp.name]
+ logger.debug('subprocess.call-ing {cmd_list}'.format(cmd_list=cmd_list))
- If the values don't validate, return a ValidationResult with 'messages' set
- to a list of strings, each of which points out an invalid value.
- """
- messages = []
- vnodes_value = set(v.lower() for v in vnodes_value)
- value_map = {'true': True, 'false': False}
+ sp = subprocess.Popen(cmd_list, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=os.environ.copy())
- for v in vnodes_value:
- if v not in value_map:
- messages.append('{} not a valid value for --vnodes option. '
- 'valid values are {} (case-insensitive)'.format(v, ', '.join(list(value_map))))
+ if args.dtest_print_tests_only:
+ stdout, stderr = sp.communicate()
- if messages:
- return ValidationResult(error_messages=messages)
+ if stderr:
+ print(stderr.decode("utf-8"))
+ result = sp.returncode
+ exit(result)
- serialized = tuple({value_map[v] for v in vnodes_value})
- return ValidationResult(serialized=serialized)
+ all_collected_test_modules = collect_test_modules(stdout)
+ joined_test_modules = "\n".join(all_collected_test_modules)
+ #print("Collected %d Test Modules" % len(all_collected_test_modules))
+ if args.dtest_print_tests_output is not None:
+ collected_tests_output_file = open(args.dtest_print_tests_output, "w")
+ collected_tests_output_file.write(joined_test_modules)
+ collected_tests_output_file.close()
+ print(joined_test_modules)
+ else:
+ while True:
+ stdout_output = sp.stdout.readline()
+ stdout_output_str = stdout_output.decode("utf-8")
+ if stdout_output_str == '' and sp.poll() is not None:
+ break
+ if stdout_output_str:
+ print(stdout_output_str.strip())
-def validate_and_serialize_options(docopt_options):
- """
- For each value that should be configured for a config object, attempt to
- serialize the passed-in strings into objects that can be used for
- configuration. If no values were passed in, use the list of options from
- the defaults above.
+ stderr_output = sp.stderr.readline()
+ stderr_output_str = stderr_output.decode("utf-8")
+ if stderr_output_str == '' and sp.poll() is not None:
+ break
+ if stderr_output_str:
+ print(stderr_output_str.strip())
- Raises a ValueError and prints an error message if any values are invalid
- or didn't serialize correctly.
- """
- vnodes = _validate_and_serialize_vnodes(docopt_options['--vnodes'])
- if vnodes.error_messages:
- raise ValueError('Validation error:\n{}'.format('\t\n'.join(list(vnodes.error_messages))))
- return GlobalConfigObject(
- vnodes=vnodes.serialized or default_config_matrix.vnodes
- )
+ exit(sp.returncode)
-def product_of_values(d):
+def collect_test_modules(stdout):
"""
- Transforms a dictionary of {key: list(configuration_options} into a tuple
- of dictionaries, each corresponding to a point in the product, with the
- values preserved at the keys where they were found in the argument.
-
- This is difficult to explain and is probably best demonstrated with an
- example:
-
- >>> from pprint import pprint
- >>> from runner import product_of_values
- >>> pprint(product_of_values(
- ... {'a': [1, 2, 3],
- ... 'b': [4, 5, 6]}
- ... ))
- ({'a': 1, 'b': 4},
- {'a': 1, 'b': 5},
- {'a': 1, 'b': 6},
- {'a': 2, 'b': 4},
- {'a': 2, 'b': 5},
- {'a': 2, 'b': 6},
- {'a': 3, 'b': 4},
- {'a': 3, 'b': 5},
- {'a': 3, 'b': 6})
-
- So, in this case, we get something like
-
- for a_value in d['a']:
- for b_value in d['b']:
- yield {'a': a_value, 'b': b_value}
-
- This method does that, but for dictionaries with arbitrary iterables at
- arbitrary numbers of keys.
+ Takes the xml-ish (no, it's not actually xml so we need to format it a bit) --collect-only output as printed
+ by pytest to stdout and normalizes it to get a list of all collected tests in a human friendly format
+ :param stdout: the stdout from pytest (should have been invoked with the --collect-only cmdline argument)
+ :return: a formatted list of collected test modules in format test_file.py::TestClass::test_function
"""
-
- # transform, e.g., {'a': [1, 2, 3], 'b': [4, 5, 6]} into
- # [[('a', 1), ('a', 2), ('a', 3)],
- # [('b', 4), ('b', 5), ('b', 6)]]
- tuple_list = [[(k, v) for v in v_list] for k, v_list in d.items()]
-
- # return the cartesian product of the flattened dict
- return tuple(dict(result) for result in product(*tuple_list))
+ # unfortunately, pytest emits xml like output -- but it's not actually xml, so we'll fail to parse
+ # if we try. first step is to fix up the pytest output to create well formatted xml
+ xml_line_regex_pattern = re.compile("^([\s])*<(Module|Class|Function|Instance) '(.*)'>")
+ is_first_module = True
+ is_first_class = True
+ has_closed_class = False
+ section_has_instance = False
+ section_has_class = False
+ test_collect_xml_lines = []
+
+ test_collect_xml_lines.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
+ test_collect_xml_lines.append("<Modules>")
+ for line in stdout.decode("utf-8").split('\n'):
+ re_ret = re.search(xml_line_regex_pattern, line)
+ if re_ret:
+ if not is_first_module and re_ret.group(2) == "Module":
+ if section_has_instance:
+ test_collect_xml_lines.append(" </Instance>")
+ if section_has_class:
+ test_collect_xml_lines.append(" </Class>")
+
+ test_collect_xml_lines.append(" </Module>")
+ is_first_class = True
+ has_closed_class= False
+ section_has_instance = False
+ section_has_class = False
+ is_first_module = False
+ elif is_first_module and re_ret.group(2) == "Module":
+ if not has_closed_class and section_has_instance:
+ test_collect_xml_lines.append(" </Instance>")
+ if not has_closed_class and section_has_class:
+ test_collect_xml_lines.append(" </Class>")
+
+ is_first_class = True
+ is_first_module = False
+ has_closed_class = False
+ section_has_instance = False
+ section_has_class = False
+ elif re_ret.group(2) == "Instance":
+ section_has_instance = True
+ elif not is_first_class and re_ret.group(2) == "Class":
+ if section_has_instance:
+ test_collect_xml_lines.append(" </Instance>")
+ if section_has_class:
+ test_collect_xml_lines.append(" </Class>")
+ has_closed_class = True
+ section_has_class = True
+ elif re_ret.group(2) == "Class":
+ is_first_class = False
+ section_has_class = True
+ has_closed_class = False
+
+ if re_ret.group(2) == "Function":
+ test_collect_xml_lines.append(" <Function name=\"{name}\"></Function>"
+ .format(name=re_ret.group(3)))
+ elif re_ret.group(2) == "Class":
+ test_collect_xml_lines.append(" <Class name=\"{name}\">".format(name=re_ret.group(3)))
+ elif re_ret.group(2) == "Module":
+ test_collect_xml_lines.append(" <Module name=\"{name}\">".format(name=re_ret.group(3)))
+ elif re_ret.group(2) == "Instance":
+ test_collect_xml_lines.append(" <Instance name=\"\">".format(name=re_ret.group(3)))
+ else:
+ test_collect_xml_lines.append(line)
+
+ test_collect_xml_lines.append(" </Instance>")
+ test_collect_xml_lines.append(" </Class>")
+ test_collect_xml_lines.append(" </Module>")
+ test_collect_xml_lines.append("</Modules>")
+
+ all_collected_test_modules = []
+
+ # parse the now valid xml
+ print("\n".join(test_collect_xml_lines))
+ test_collect_xml = BeautifulSoup("\n".join(test_collect_xml_lines), "lxml-xml")
+
+ # find all Modules (followed by classes in those modules, and then finally functions)
+ for pytest_module in test_collect_xml.findAll("Module"):
+ for test_class_name in pytest_module.findAll("Class"):
+ for function_name in test_class_name.findAll("Function"):
+ # adds to test list in format like test_file.py::TestClass::test_function for every test function found
+ all_collected_test_modules.append("{module_name}::{class_name}::{function_name}"
+ .format(module_name=pytest_module.attrs['name'],
+ class_name=test_class_name.attrs['name'],
+ function_name=function_name.attrs['name']))
+
+ return all_collected_test_modules
if __name__ == '__main__':
- options = docopt(__doc__)
- validated_options = validate_and_serialize_options(options)
-
- nose_options = options['--nose-options'] or ''
- nose_option_list = nose_options.split()
- test_list = options['TESTS']
- nose_argv = nose_option_list + test_list
-
- verbosity = 1 # default verbosity level
- if options['--runner-debug']:
- verbosity = 2
- if options['--runner-quiet']: # --debug and --quiet are mutually exclusive, enforced by docopt
- verbosity = 0
-
- debug = print if verbosity >= 2 else _noop
- output = print if verbosity >= 1 else _noop
-
- # Get dictionaries corresponding to each point in the configuration matrix
- # we want to run, then generate a config object for each of them.
- debug('Generating configurations from the following matrix:\n\t{}'.format(validated_options))
- all_configs = tuple(GlobalConfigObject(**d) for d in
- product_of_values(validated_options._asdict()))
- output('About to run nosetests with config objects:\n'
- '\t{configs}\n'.format(configs='\n\t'.join(map(repr, all_configs))))
-
- results = []
- for config in all_configs:
- # These properties have to hold if we want to evaluate their reprs
- # below in the generated file.
- assert eval(repr(config), {'GlobalConfigObject': GlobalConfigObject}, {}) == config
- assert eval(repr(nose_argv), {}, {}) == nose_argv
-
- output('Running dtests with config object {}'.format(config))
-
- # Generate a file that runs nose, passing in config as the
- # configuration object.
- #
- # Yes, this is icky. The reason we do it is because we're dealing with
- # global configuration. We've decided global, nosetests-run-level
- # configuration is the way to go. This means we don't want to call
- # nose.main() multiple times in the same Python interpreter -- I have
- # not yet found a way to re-execute modules (thus getting new
- # module-level configuration) for each call. This didn't even work for
- # me with exec(script, {}, {}). So, here we are.
- #
- # How do we execute code in a new interpreter each time? Generate the
- # code as text, then shell out to a new interpreter.
- to_execute = (
- "import nose\n" +
- "from plugins.dtestconfig import DtestConfigPlugin, GlobalConfigObject\n" +
- "from plugins.dtestxunit import DTestXunit\n" +
- "from plugins.dtesttag import DTestTag\n" +
- "from plugins.dtestcollect import DTestCollect\n" +
- "import sys\n" +
- "print sys.getrecursionlimit()\n" +
- "print sys.setrecursionlimit(8000)\n" +
- ("nose.main(addplugins=[DtestConfigPlugin({config}), DTestXunit(), DTestCollect(), DTestTag()])\n" if "TEST_TAG" in environ else "nose.main(addplugins=[DtestConfigPlugin({config}), DTestCollect(), DTestXunit()])\n")
- ).format(config=repr(config))
- temp = NamedTemporaryFile(dir=getcwd())
- debug('Writing the following to {}:'.format(temp.name))
-
- debug('```\n{to_execute}```\n'.format(to_execute=to_execute))
- temp.write(to_execute)
- temp.flush()
-
- # We pass nose_argv as options to the python call to maintain
- # compatibility with the nosetests command. Arguments passed in via the
- # command line are treated one way, args passed in as
- # nose.main(argv=...) are treated another. Compare with the options
- # -xsv for an example.
- cmd_list = [sys.executable, temp.name] + nose_argv
- debug('subprocess.call-ing {cmd_list}'.format(cmd_list=cmd_list))
-
- if options['--dry-run']:
- print('Would run the following command:\n\t{}'.format(cmd_list))
- with open(temp.name, 'r') as f:
- contents = f.read()
- print('{temp_name} contains:\n```\n{contents}```\n'.format(
- temp_name=temp.name,
- contents=contents
- ))
- else:
- results.append(subprocess.call(cmd_list, env=os.environ.copy()))
- # separate the end of the last subprocess.call output from the
- # beginning of the next by printing a newline.
- print()
-
- # If this answer:
- # http://stackoverflow.com/a/21788998/3408454
- # is to be believed, nosetests will exit with 0 on success, 1 on test or
- # other failure, and 2 on printing usage. We'll just grab the max of the
- # runs we saw -- if one printed usage, the whole run "printed usage", if
- # none printed usage, and one or more failed, we failed, else success.
- if not results:
- results = [0]
- exit(max(results))
+ RunDTests().run(sys.argv[1:])
http://git-wip-us.apache.org/repos/asf/cassandra-dtest/blob/49b2dda4/schema_metadata_test.py
----------------------------------------------------------------------
diff --git a/schema_metadata_test.py b/schema_metadata_test.py
index baf8b5a..fdfcf56 100644
--- a/schema_metadata_test.py
+++ b/schema_metadata_test.py
@@ -1,10 +1,13 @@
+import pytest
+import logging
+
from collections import defaultdict
from uuid import uuid4
-from nose.tools import assert_equal, assert_in
+from dtest import Tester, create_ks
-from dtest import Tester, debug, create_ks
-from tools.decorators import since
+since = pytest.mark.since
+logger = logging.getLogger(__name__)
def establish_durable_writes_keyspace(version, session, table_name_prefix=""):
@@ -32,11 +35,10 @@ def verify_durable_writes_keyspace(created_on_version, current_version, keyspace
"durable_writes_true": True,
"durable_writes_false": False
}
- for keyspace, is_durable in expected.iteritems():
+ for keyspace, is_durable in expected.items():
keyspace_name = _cql_name_builder(table_name_prefix, keyspace)
meta = session.cluster.metadata.keyspaces[keyspace_name]
- assert_equal(is_durable, meta.durable_writes,
- "keyspace [{}] had durable_writes of [{}] should be [{}]".format(keyspace_name, meta.durable_writes, is_durable))
+ assert is_durable == meta.durable_writes, "keyspace [{}] had durable_writes of [{}] should be [{}]".format(keyspace_name, meta.durable_writes, is_durable)
def establish_indexes_table(version, session, table_name_prefix=""):
@@ -53,29 +55,29 @@ def establish_indexes_table(version, session, table_name_prefix=""):
session.execute(cql.format(table_name))
index_name = _cql_name_builder("idx_" + table_name_prefix, table_name)
- debug("table name: [{}], index name: [{}], prefix: [{}]".format(table_name, index_name, table_name_prefix))
+ logger.debug("table name: [{}], index name: [{}], prefix: [{}]".format(table_name, index_name, table_name_prefix))
session.execute("CREATE INDEX {0} ON {1}( d )".format(index_name, table_name))
def verify_indexes_table(created_on_version, current_version, keyspace, session, table_name_prefix=""):
table_name = _cql_name_builder(table_name_prefix, "test_indexes")
index_name = _cql_name_builder("idx_" + table_name_prefix, table_name)
- debug("table name: [{}], index name: [{}], prefix: [{}]".format(table_name, index_name, table_name_prefix))
+ logger.debug("table name: [{}], index name: [{}], prefix: [{}]".format(table_name, index_name, table_name_prefix))
meta = session.cluster.metadata.keyspaces[keyspace].indexes[index_name]
- assert_equal('d', meta.index_options['target'])
+ assert 'd' == meta.index_options['target']
meta = session.cluster.metadata.keyspaces[keyspace].tables[table_name]
- assert_equal(1, len(meta.clustering_key))
- assert_equal('c', meta.clustering_key[0].name)
+ assert 1 == len(meta.clustering_key)
+ assert 'c' == meta.clustering_key[0].name
- assert_equal(1, len(meta.indexes))
+ assert 1 == len(meta.indexes)
- assert_equal({'target': 'd'}, meta.indexes[index_name].index_options)
- assert_equal(3, len(meta.primary_key))
- assert_equal('a', meta.primary_key[0].name)
- assert_equal('b', meta.primary_key[1].name)
- assert_equal('c', meta.primary_key[2].name)
+ assert {'target': 'd'} == meta.indexes[index_name].index_options
+ assert 3 == len(meta.primary_key)
+ assert 'a' == meta.primary_key[0].name
+ assert 'b' == meta.primary_key[1].name
+ assert 'c' == meta.primary_key[2].name
def establish_clustering_order_table(version, session, table_name_prefix=""):
@@ -96,13 +98,13 @@ def establish_clustering_order_table(version, session, table_name_prefix=""):
def verify_clustering_order_table(created_on_version, current_version, keyspace, session, table_name_prefix=""):
table_name = _cql_name_builder(table_name_prefix, "test_clustering_order")
meta = session.cluster.metadata.keyspaces[keyspace].tables[table_name]
- assert_equal(0, len(meta.indexes))
- assert_equal(2, len(meta.primary_key))
- assert_equal('event_type', meta.primary_key[0].name)
- assert_equal('insertion_time', meta.primary_key[1].name)
- assert_equal(1, len(meta.clustering_key))
- assert_equal('insertion_time', meta.clustering_key[0].name)
- assert_in('insertion_time DESC', meta.as_cql_query())
+ assert 0 == len(meta.indexes)
+ assert 2 == len(meta.primary_key)
+ assert 'event_type' == meta.primary_key[0].name
+ assert 'insertion_time' == meta.primary_key[1].name
+ assert 1 == len(meta.clustering_key)
+ assert 'insertion_time' == meta.clustering_key[0].name
+ assert 'insertion_time DESC' in meta.as_cql_query()
def establish_compact_storage_table(version, session, table_name_prefix=""):
@@ -123,16 +125,16 @@ def establish_compact_storage_table(version, session, table_name_prefix=""):
def verify_compact_storage_table(created_on_version, current_version, keyspace, session, table_name_prefix=""):
table_name = _cql_name_builder(table_name_prefix, "test_compact_storage")
meta = session.cluster.metadata.keyspaces[keyspace].tables[table_name]
- assert_equal(3, len(meta.columns))
- assert_equal(2, len(meta.primary_key))
- assert_equal(1, len(meta.clustering_key))
- assert_equal('sub_block_id', meta.clustering_key[0].name)
- assert_equal('block_id', meta.primary_key[0].name)
- assert_equal('uuid', meta.primary_key[0].cql_type)
- assert_equal('sub_block_id', meta.primary_key[1].name)
- assert_equal('int', meta.primary_key[1].cql_type)
- assert_equal(1, len(meta.clustering_key))
- assert_equal('sub_block_id', meta.clustering_key[0].name)
+ assert 3 == len(meta.columns)
+ assert 2 == len(meta.primary_key)
+ assert 1 == len(meta.clustering_key)
+ assert 'sub_block_id' == meta.clustering_key[0].name
+ assert 'block_id' == meta.primary_key[0].name
+ assert 'uuid' == meta.primary_key[0].cql_type
+ assert 'sub_block_id' == meta.primary_key[1].name
+ assert 'int' == meta.primary_key[1].cql_type
+ assert 1 == len(meta.clustering_key)
+ assert 'sub_block_id' == meta.clustering_key[0].name
def establish_compact_storage_composite_table(version, session, table_name_prefix=""):
@@ -153,19 +155,19 @@ def establish_compact_storage_composite_table(version, session, table_name_prefi
def verify_compact_storage_composite_table(created_on_version, current_version, keyspace, session, table_name_prefix=""):
table_name = _cql_name_builder(table_name_prefix, "test_compact_storage_composite")
meta = session.cluster.metadata.keyspaces[keyspace].tables[table_name]
- assert_equal(4, len(meta.columns))
- assert_equal(3, len(meta.primary_key))
- assert_equal('key', meta.primary_key[0].name)
- assert_equal('text', meta.primary_key[0].cql_type)
- assert_equal('column1', meta.primary_key[1].name)
- assert_equal('int', meta.primary_key[1].cql_type)
- assert_equal('column2', meta.primary_key[2].name)
- assert_equal('int', meta.primary_key[2].cql_type)
- assert_equal(2, len(meta.clustering_key))
- assert_equal('column1', meta.clustering_key[0].name)
- assert_equal('int', meta.clustering_key[0].cql_type)
- assert_equal('column2', meta.clustering_key[1].name)
- assert_equal('int', meta.clustering_key[1].cql_type)
+ assert 4 == len(meta.columns)
+ assert 3 == len(meta.primary_key)
+ assert 'key' == meta.primary_key[0].name
+ assert 'text' == meta.primary_key[0].cql_type
+ assert 'column1' == meta.primary_key[1].name
+ assert 'int' == meta.primary_key[1].cql_type
+ assert 'column2' == meta.primary_key[2].name
+ assert 'int' == meta.primary_key[2].cql_type
+ assert 2 == len(meta.clustering_key)
+ assert 'column1' == meta.clustering_key[0].name
+ assert 'int' == meta.clustering_key[0].cql_type
+ assert 'column2' == meta.clustering_key[1].name
+ assert 'int' == meta.clustering_key[1].cql_type
def establish_nondefault_table_settings(version, session, table_name_prefix=""):
@@ -213,45 +215,45 @@ def verify_nondefault_table_settings(created_on_version, current_version, keyspa
table_name = _cql_name_builder(table_name_prefix, "test_nondefault_settings")
meta = session.cluster.metadata.keyspaces[keyspace].tables[table_name]
- assert_equal('insightful information', meta.options['comment'])
- assert_equal(0.88, meta.options['dclocal_read_repair_chance'])
- assert_equal(9999, meta.options['gc_grace_seconds'])
- assert_equal(0.99, meta.options['read_repair_chance'])
- assert_equal(0.5, meta.options['bloom_filter_fp_chance'])
+ assert 'insightful information' == meta.options['comment']
+ assert 0.88 == meta.options['dclocal_read_repair_chance']
+ assert 9999 == meta.options['gc_grace_seconds']
+ assert 0.99 == meta.options['read_repair_chance']
+ assert 0.5 == meta.options['bloom_filter_fp_chance']
if created_on_version >= '2.1':
- assert_equal(86400, meta.options['default_time_to_live'])
- assert_equal(1, meta.options['min_index_interval'])
- assert_equal(20, meta.options['max_index_interval'])
+ assert 86400 == meta.options['default_time_to_live']
+ assert 1 == meta.options['min_index_interval']
+ assert 20 == meta.options['max_index_interval']
if created_on_version >= '3.0':
- assert_equal('55PERCENTILE', meta.options['speculative_retry'])
- assert_equal(2121, meta.options['memtable_flush_period_in_ms'])
+ assert '55PERCENTILE' == meta.options['speculative_retry']
+ assert 2121 == meta.options['memtable_flush_period_in_ms']
if current_version >= '3.0':
- assert_equal('org.apache.cassandra.io.compress.DeflateCompressor', meta.options['compression']['class'])
- assert_equal('128', meta.options['compression']['chunk_length_in_kb'])
- assert_equal('org.apache.cassandra.db.compaction.LeveledCompactionStrategy', meta.options['compaction']['class'])
+ assert 'org.apache.cassandra.io.compress.DeflateCompressor' == meta.options['compression']['class']
+ assert '128' == meta.options['compression']['chunk_length_in_kb']
+ assert 'org.apache.cassandra.db.compaction.LeveledCompactionStrategy' == meta.options['compaction']['class']
if '2.1' <= current_version < '3.0':
- assert_equal('{"keys":"NONE", "rows_per_partition":"ALL"}', meta.options['caching'])
- assert_in('"chunk_length_kb":"128"', meta.options['compression_parameters'])
- assert_in('"sstable_compression":"org.apache.cassandra.io.compress.DeflateCompressor"', meta.options['compression_parameters'])
+ assert '{"keys":"NONE", "rows_per_partition":"ALL"}' == meta.options['caching']
+ assert '"chunk_length_kb":"128"' in meta.options['compression_parameters']
+ assert '"sstable_compression":"org.apache.cassandra.io.compress.DeflateCompressor"' in meta.options['compression_parameters']
elif current_version >= '3.0':
- assert_equal('NONE', meta.options['caching']['keys'])
- assert_equal('ALL', meta.options['caching']['rows_per_partition'])
- assert_equal('org.apache.cassandra.io.compress.DeflateCompressor', meta.options['compression']['class'])
- assert_equal('128', meta.options['compression']['chunk_length_in_kb'])
- assert_equal('org.apache.cassandra.db.compaction.LeveledCompactionStrategy', meta.options['compaction']['class'])
+ assert 'NONE' == meta.options['caching']['keys']
+ assert 'ALL' == meta.options['caching']['rows_per_partition']
+ assert 'org.apache.cassandra.io.compress.DeflateCompressor' == meta.options['compression']['class']
+ assert '128' == meta.options['compression']['chunk_length_in_kb']
+ assert 'org.apache.cassandra.db.compaction.LeveledCompactionStrategy' == meta.options['compaction']['class']
else:
- assert_equal('ROWS_ONLY', meta.options['caching'])
+ assert 'ROWS_ONLY' == meta.options['caching']
- assert_equal(2, len(meta.partition_key))
- assert_equal(meta.partition_key[0].name, 'a')
- assert_equal(meta.partition_key[1].name, 'b')
+ assert 2 == len(meta.partition_key)
+ assert meta.partition_key[0].name == 'a'
+ assert meta.partition_key[1].name == 'b'
- assert_equal(1, len(meta.clustering_key))
- assert_equal(meta.clustering_key[0].name, 'c')
+ assert 1 == len(meta.clustering_key)
+ assert meta.clustering_key[0].name == 'c'
def establish_uda(version, session, table_name_prefix=""):
@@ -281,13 +283,13 @@ def verify_uda(created_on_version, current_version, keyspace, session, table_nam
function_name = _cql_name_builder(table_name_prefix, "test_uda_function")
aggregate_name = _cql_name_builder(table_name_prefix, "test_uda_aggregate")
- assert_in(function_name + "(int,int)", session.cluster.metadata.keyspaces[keyspace].functions.keys())
- assert_in(aggregate_name + "(int)", session.cluster.metadata.keyspaces[keyspace].aggregates.keys())
+ assert function_name + "(int,int)" in list(session.cluster.metadata.keyspaces[keyspace].functions.keys())
+ assert aggregate_name + "(int)" in list(session.cluster.metadata.keyspaces[keyspace].aggregates.keys())
aggr_meta = session.cluster.metadata.keyspaces[keyspace].aggregates[aggregate_name + "(int)"]
- assert_equal(function_name, aggr_meta.state_func)
- assert_equal('int', aggr_meta.state_type)
- assert_equal('int', aggr_meta.return_type)
+ assert function_name == aggr_meta.state_func
+ assert 'int' == aggr_meta.state_type
+ assert 'int' == aggr_meta.return_type
def establish_udf(version, session, table_name_prefix=""):
@@ -303,13 +305,13 @@ def verify_udf(created_on_version, current_version, keyspace, session, table_nam
if created_on_version < '2.2':
return
function_name = _cql_name_builder(table_name_prefix, "test_udf")
- assert_in(function_name + "(double)", session.cluster.metadata.keyspaces[keyspace].functions.keys())
+ assert function_name + "(double)" in list(session.cluster.metadata.keyspaces[keyspace].functions.keys())
meta = session.cluster.metadata.keyspaces[keyspace].functions[function_name + "(double)"]
- assert_equal('java', meta.language)
- assert_equal('double', meta.return_type)
- assert_equal(['double'], meta.argument_types)
- assert_equal(['input'], meta.argument_names)
- assert_equal('return Double.valueOf(Math.log(input.doubleValue()));', meta.body)
+ assert 'java' == meta.language
+ assert 'double' == meta.return_type
+ assert ['double'] == meta.argument_types
+ assert ['input'] == meta.argument_names
+ assert 'return Double.valueOf(Math.log(input.doubleValue()));' == meta.body
def establish_udt_table(version, session, table_name_prefix=""):
@@ -330,13 +332,13 @@ def verify_udt_table(created_on_version, current_version, keyspace, session, tab
table_name = _cql_name_builder(table_name_prefix, "test_udt")
meta = session.cluster.metadata.keyspaces[keyspace].user_types[table_name]
- assert_equal(meta.field_names, ['street', 'city', 'zip'])
- assert_equal('street', meta.field_names[0])
- assert_equal('text', meta.field_types[0])
- assert_equal('city', meta.field_names[1])
- assert_equal('text', meta.field_types[1])
- assert_equal('zip', meta.field_names[2])
- assert_equal('int', meta.field_types[2])
+ assert meta.field_names == ['street', 'city', 'zip']
+ assert 'street' == meta.field_names[0]
+ assert 'text' == meta.field_types[0]
+ assert 'city' == meta.field_names[1]
+ assert 'text' == meta.field_types[1]
+ assert 'zip' == meta.field_names[2]
+ assert 'int' == meta.field_types[2]
def establish_static_column_table(version, session, table_name_prefix=""):
@@ -358,15 +360,15 @@ def verify_static_column_table(created_on_version, current_version, keyspace, se
return
table_name = _cql_name_builder(table_name_prefix, "test_static_column")
meta = session.cluster.metadata.keyspaces[keyspace].tables[table_name]
- assert_equal(4, len(meta.columns))
- assert_equal('text', meta.columns['user'].cql_type)
- assert_equal(False, meta.columns['user'].is_static)
- assert_equal('int', meta.columns['balance'].cql_type)
- assert_equal(True, meta.columns['balance'].is_static)
- assert_equal('int', meta.columns['expense_id'].cql_type)
- assert_equal(False, meta.columns['expense_id'].is_static)
- assert_equal('int', meta.columns['amount'].cql_type)
- assert_equal(False, meta.columns['amount'].is_static)
+ assert 4 == len(meta.columns)
+ assert 'text' == meta.columns['user'].cql_type
+ assert False == meta.columns['user'].is_static
+ assert 'int' == meta.columns['balance'].cql_type
+ assert True == meta.columns['balance'].is_static
+ assert 'int' == meta.columns['expense_id'].cql_type
+ assert False == meta.columns['expense_id'].is_static
+ assert 'int' == meta.columns['amount'].cql_type
+ assert False == meta.columns['amount'].is_static
def establish_collection_datatype_table(version, session, table_name_prefix=""):
@@ -399,24 +401,24 @@ def verify_collection_datatype_table(created_on_version, current_version, keyspa
table_name = _cql_name_builder(table_name_prefix, "test_collection_datatypes")
meta = session.cluster.metadata.keyspaces[keyspace].tables[table_name]
if created_on_version > '2.1':
- assert_equal(13, len(meta.columns))
+ assert 13 == len(meta.columns)
else:
- assert_equal(7, len(meta.columns))
+ assert 7 == len(meta.columns)
- assert_equal('list<int>', meta.columns['a'].cql_type)
- assert_equal('list<text>', meta.columns['b'].cql_type)
- assert_equal('set<int>', meta.columns['c'].cql_type)
- assert_equal('set<text>', meta.columns['d'].cql_type)
- assert_equal('map<text, text>', meta.columns['e'].cql_type)
- assert_equal('map<text, int>', meta.columns['f'].cql_type)
+ assert 'list<int>' == meta.columns['a'].cql_type
+ assert 'list<text>' == meta.columns['b'].cql_type
+ assert 'set<int>' == meta.columns['c'].cql_type
+ assert 'set<text>' == meta.columns['d'].cql_type
+ assert 'map<text, text>' == meta.columns['e'].cql_type
+ assert 'map<text, int>' == meta.columns['f'].cql_type
if created_on_version > '2.1':
- assert_equal('frozen<list<int>>', meta.columns['g'].cql_type)
- assert_equal('frozen<list<text>>', meta.columns['h'].cql_type)
- assert_equal('frozen<set<int>>', meta.columns['i'].cql_type)
- assert_equal('frozen<set<text>>', meta.columns['j'].cql_type)
- assert_equal('frozen<map<text, text>>', meta.columns['k'].cql_type)
- assert_equal('frozen<map<text, int>>', meta.columns['l'].cql_type)
+ assert 'frozen<list<int>>' == meta.columns['g'].cql_type
+ assert 'frozen<list<text>>' == meta.columns['h'].cql_type
+ assert 'frozen<set<int>>' == meta.columns['i'].cql_type
+ assert 'frozen<set<text>>' == meta.columns['j'].cql_type
+ assert 'frozen<map<text, text>>' == meta.columns['k'].cql_type
+ assert 'frozen<map<text, int>>' == meta.columns['l'].cql_type
def establish_basic_datatype_table(version, session, table_name_prefix=""):
@@ -453,33 +455,33 @@ def verify_basic_datatype_table(created_on_version, current_version, keyspace, s
table_name = _cql_name_builder(table_name_prefix, "test_basic_datatypes")
meta = session.cluster.metadata.keyspaces[keyspace].tables[table_name]
if created_on_version > '2.2':
- assert_equal(19, len(meta.columns))
+ assert 19 == len(meta.columns)
else:
- assert_equal(15, len(meta.columns))
-
- assert_equal(1, len(meta.primary_key))
- assert_equal('b', meta.primary_key[0].name)
-
- assert_equal('ascii', meta.columns['a'].cql_type)
- assert_equal('bigint', meta.columns['b'].cql_type)
- assert_equal('blob', meta.columns['c'].cql_type)
- assert_equal('boolean', meta.columns['d'].cql_type)
- assert_equal('decimal', meta.columns['e'].cql_type)
- assert_equal('double', meta.columns['f'].cql_type)
- assert_equal('float', meta.columns['g'].cql_type)
- assert_equal('inet', meta.columns['h'].cql_type)
- assert_equal('int', meta.columns['i'].cql_type)
- assert_equal('text', meta.columns['j'].cql_type)
- assert_equal('timestamp', meta.columns['k'].cql_type)
- assert_equal('timeuuid', meta.columns['l'].cql_type)
- assert_equal('uuid', meta.columns['m'].cql_type)
- assert_equal('text', meta.columns['n'].cql_type)
- assert_equal('varint', meta.columns['o'].cql_type)
+ assert 15 == len(meta.columns)
+
+ assert 1 == len(meta.primary_key)
+ assert 'b' == meta.primary_key[0].name
+
+ assert 'ascii' == meta.columns['a'].cql_type
+ assert 'bigint' == meta.columns['b'].cql_type
+ assert 'blob' == meta.columns['c'].cql_type
+ assert 'boolean' == meta.columns['d'].cql_type
+ assert 'decimal' == meta.columns['e'].cql_type
+ assert 'double' == meta.columns['f'].cql_type
+ assert 'float' == meta.columns['g'].cql_type
+ assert 'inet' == meta.columns['h'].cql_type
+ assert 'int' == meta.columns['i'].cql_type
+ assert 'text' == meta.columns['j'].cql_type
+ assert 'timestamp' == meta.columns['k'].cql_type
+ assert 'timeuuid' == meta.columns['l'].cql_type
+ assert 'uuid' == meta.columns['m'].cql_type
+ assert 'text' == meta.columns['n'].cql_type
+ assert 'varint' == meta.columns['o'].cql_type
if created_on_version > '2.2':
- assert_equal('date', meta.columns['p'].cql_type)
- assert_equal('smallint', meta.columns['q'].cql_type)
- assert_equal('time', meta.columns['r'].cql_type)
- assert_equal('tinyint', meta.columns['s'].cql_type)
+ assert 'date' == meta.columns['p'].cql_type
+ assert 'smallint' == meta.columns['q'].cql_type
+ assert 'time' == meta.columns['r'].cql_type
+ assert 'tinyint' == meta.columns['s'].cql_type
def _cql_name_builder(prefix, table_name):
@@ -495,10 +497,9 @@ def _cql_name_builder(prefix, table_name):
class TestSchemaMetadata(Tester):
-
- def setUp(self):
- Tester.setUp(self)
- cluster = self.cluster
+ @pytest.fixture(scope='function', autouse=True)
+ def fixture_set_cluster_settings(self, fixture_dtest_setup):
+ cluster = fixture_dtest_setup.cluster
cluster.schema_event_refresh_window = 0
if cluster.version() >= '3.0':
@@ -508,101 +509,101 @@ class TestSchemaMetadata(Tester):
cluster.set_configuration_options({'enable_user_defined_functions': 'true'})
cluster.populate(1).start()
- self.session = self.patient_cql_connection(cluster.nodelist()[0])
+ self.session = fixture_dtest_setup.patient_cql_connection(cluster.nodelist()[0])
create_ks(self.session, 'ks', 1)
def _keyspace_meta(self, keyspace_name="ks"):
self.session.cluster.refresh_schema_metadata()
return self.session.cluster.metadata.keyspaces[keyspace_name]
- def creating_and_dropping_keyspace_test(self):
+ def test_creating_and_dropping_keyspace(self):
starting_keyspace_count = len(self.session.cluster.metadata.keyspaces)
- self.assertEqual(True, self._keyspace_meta().durable_writes)
+ assert True == self._keyspace_meta().durable_writes
self.session.execute("""
CREATE KEYSPACE so_long
WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}
AND durable_writes = false
""")
- self.assertEqual(False, self._keyspace_meta('so_long').durable_writes)
+ assert False == self._keyspace_meta('so_long').durable_writes
self.session.execute("DROP KEYSPACE so_long")
- self.assertEqual(starting_keyspace_count, len(self.session.cluster.metadata.keyspaces))
+ assert starting_keyspace_count == len(self.session.cluster.metadata.keyspaces)
- def creating_and_dropping_table_test(self):
+ def test_creating_and_dropping_table(self):
self.session.execute("create table born_to_die (id uuid primary key, name varchar)")
meta = self._keyspace_meta().tables['born_to_die']
- self.assertEqual('ks', meta.keyspace_name)
- self.assertEqual('born_to_die', meta.name)
- self.assertEqual(1, len(meta.partition_key))
- self.assertEqual('id', meta.partition_key[0].name)
- self.assertEqual(2, len(meta.columns))
- self.assertIsNotNone(meta.columns.get('id'))
- self.assertEqual('uuid', meta.columns['id'].cql_type)
- self.assertIsNotNone(meta.columns.get('name'))
- self.assertEqual('text', meta.columns['name'].cql_type)
- self.assertEqual(0, len(meta.clustering_key))
- self.assertEqual(0, len(meta.triggers))
- self.assertEqual(0, len(meta.indexes))
+ assert 'ks' == meta.keyspace_name
+ assert 'born_to_die' == meta.name
+ assert 1 == len(meta.partition_key)
+ assert 'id' == meta.partition_key[0].name
+ assert 2 == len(meta.columns)
+ assert meta.columns.get('id') is not None
+ assert 'uuid' == meta.columns['id'].cql_type
+ assert meta.columns.get('name') is not None
+ assert 'text' == meta.columns['name'].cql_type
+ assert 0 == len(meta.clustering_key)
+ assert 0 == len(meta.triggers)
+ assert 0 == len(meta.indexes)
self.session.execute("drop table born_to_die")
- self.assertIsNone(self._keyspace_meta().tables.get('born_to_die'))
+ assert self._keyspace_meta().tables.get('born_to_die') is None
- def creating_and_dropping_table_with_2ary_indexes_test(self):
- self.assertEqual(0, len(self._keyspace_meta().indexes))
+ def test_creating_and_dropping_table_with_2ary_indexes(self):
+ assert 0 == len(self._keyspace_meta().indexes)
self.session.execute("create table born_to_die (id uuid primary key, name varchar)")
self.session.execute("create index ix_born_to_die_name on born_to_die(name)")
- self.assertEqual(1, len(self._keyspace_meta().indexes))
+ assert 1 == len(self._keyspace_meta().indexes)
ix_meta = self._keyspace_meta().indexes['ix_born_to_die_name']
- self.assertEqual('ix_born_to_die_name', ix_meta.name)
+ assert 'ix_born_to_die_name' == ix_meta.name
- self.assertEqual({'target': 'name'}, ix_meta.index_options)
- self.assertEqual('COMPOSITES', ix_meta.kind)
+ assert {'target': 'name'} == ix_meta.index_options
+ assert 'COMPOSITES' == ix_meta.kind
self.session.execute("drop table born_to_die")
- self.assertIsNone(self._keyspace_meta().tables.get('born_to_die'))
- self.assertIsNone(self._keyspace_meta().indexes.get('ix_born_to_die_name'))
- self.assertEqual(0, len(self._keyspace_meta().indexes))
+ assert self._keyspace_meta().tables.get('born_to_die') is None
+ assert self._keyspace_meta().indexes.get('ix_born_to_die_name') is None
+ assert 0 == len(self._keyspace_meta().indexes)
@since('2.1')
- def creating_and_dropping_user_types_test(self):
- self.assertEqual(0, len(self._keyspace_meta().user_types))
+ def test_creating_and_dropping_user_types(self):
+ assert 0 == len(self._keyspace_meta().user_types)
self.session.execute("CREATE TYPE soon_to_die (foo text, bar int)")
- self.assertEqual(1, len(self._keyspace_meta().user_types))
+ assert 1 == len(self._keyspace_meta().user_types)
ut_meta = self._keyspace_meta().user_types['soon_to_die']
- self.assertEqual('ks', ut_meta.keyspace)
- self.assertEqual('soon_to_die', ut_meta.name)
- self.assertEqual(['foo', 'bar'], ut_meta.field_names)
- self.assertEqual(['text', 'int'], ut_meta.field_types)
+ assert 'ks' == ut_meta.keyspace
+ assert 'soon_to_die' == ut_meta.name
+ assert ['foo', 'bar'] == ut_meta.field_names
+ assert ['text', 'int'] == ut_meta.field_types
self.session.execute("DROP TYPE soon_to_die")
- self.assertEqual(0, len(self._keyspace_meta().user_types))
+ assert 0 == len(self._keyspace_meta().user_types)
@since('2.2')
- def creating_and_dropping_udf_test(self):
- self.assertEqual(0, len(self._keyspace_meta().functions), "expected to start with no indexes")
+ def test_creating_and_dropping_udf(self):
+ assert 0 == len(self._keyspace_meta().functions), "expected to start with no indexes"
self.session.execute("""
CREATE OR REPLACE FUNCTION ks.wasteful_function (input double)
CALLED ON NULL INPUT
RETURNS double
LANGUAGE java AS 'return Double.valueOf(Math.log(input.doubleValue()));';
""")
- self.assertEqual(1, len(self._keyspace_meta().functions), "udf count should be 1")
+ assert 1 == len(self._keyspace_meta().functions), "udf count should be 1"
udf_meta = self._keyspace_meta().functions['wasteful_function(double)']
- self.assertEqual('ks', udf_meta.keyspace)
- self.assertEqual('wasteful_function', udf_meta.name)
- self.assertEqual(['double'], udf_meta.argument_types)
- self.assertEqual(['input'], udf_meta.argument_names)
- self.assertEqual('double', udf_meta.return_type)
- self.assertEqual('java', udf_meta.language)
- self.assertEqual('return Double.valueOf(Math.log(input.doubleValue()));', udf_meta.body)
- self.assertTrue(udf_meta.called_on_null_input)
+ assert 'ks' == udf_meta.keyspace
+ assert 'wasteful_function' == udf_meta.name
+ assert ['double'] == udf_meta.argument_types
+ assert ['input'] == udf_meta.argument_names
+ assert 'double' == udf_meta.return_type
+ assert 'java' == udf_meta.language
+ assert 'return Double.valueOf(Math.log(input.doubleValue()));' == udf_meta.body
+ assert udf_meta.called_on_null_input
self.session.execute("DROP FUNCTION ks.wasteful_function")
- self.assertEqual(0, len(self._keyspace_meta().functions), "expected udf list to be back to zero")
+ assert 0 == len(self._keyspace_meta().functions), "expected udf list to be back to zero"
@since('2.2')
- def creating_and_dropping_uda_test(self):
- self.assertEqual(0, len(self._keyspace_meta().functions), "expected to start with no indexes")
- self.assertEqual(0, len(self._keyspace_meta().aggregates), "expected to start with no aggregates")
+ def test_creating_and_dropping_uda(self):
+ assert 0 == len(self._keyspace_meta().functions), "expected to start with no indexes"
+ assert 0 == len(self._keyspace_meta().aggregates), "expected to start with no aggregates"
self.session.execute('''
CREATE FUNCTION ks.max_val(current int, candidate int)
CALLED ON NULL INPUT
@@ -615,86 +616,86 @@ class TestSchemaMetadata(Tester):
STYPE int
INITCOND -1
''')
- self.assertEqual(1, len(self._keyspace_meta().functions), "udf count should be 1")
- self.assertEqual(1, len(self._keyspace_meta().aggregates), "uda count should be 1")
+ assert 1 == len(self._keyspace_meta().functions), "udf count should be 1"
+ assert 1 == len(self._keyspace_meta().aggregates), "uda count should be 1"
udf_meta = self._keyspace_meta().functions['max_val(int,int)']
uda_meta = self._keyspace_meta().aggregates['kind_of_max_agg(int)']
- self.assertEqual('ks', udf_meta.keyspace)
- self.assertEqual('max_val', udf_meta.name)
- self.assertEqual(['int', 'int'], udf_meta.argument_types)
- self.assertEqual(['current', 'candidate'], udf_meta.argument_names)
- self.assertEqual('int', udf_meta.return_type)
- self.assertEqual('java', udf_meta.language)
- self.assertEqual('if (current == null) return candidate; else return Math.max(current, candidate);', udf_meta.body)
- self.assertTrue(udf_meta.called_on_null_input)
-
- self.assertEqual('ks', uda_meta.keyspace)
- self.assertEqual('kind_of_max_agg', uda_meta.name)
- self.assertEqual(['int'], uda_meta.argument_types)
- self.assertEqual('max_val', uda_meta.state_func)
- self.assertEqual('int', uda_meta.state_type)
- self.assertEqual(None, uda_meta.final_func)
- self.assertEqual('-1', uda_meta.initial_condition)
- self.assertEqual('int', uda_meta.return_type)
+ assert 'ks' == udf_meta.keyspace
+ assert 'max_val' == udf_meta.name
+ assert ['int', 'int'] == udf_meta.argument_types
+ assert ['current', 'candidate'] == udf_meta.argument_names
+ assert 'int' == udf_meta.return_type
+ assert 'java' == udf_meta.language
+ assert 'if (current == null) return candidate; else return Math.max(current, candidate);' == udf_meta.body
+ assert udf_meta.called_on_null_input
+
+ assert 'ks' == uda_meta.keyspace
+ assert 'kind_of_max_agg' == uda_meta.name
+ assert ['int'] == uda_meta.argument_types
+ assert 'max_val' == uda_meta.state_func
+ assert 'int' == uda_meta.state_type
+ assert None == uda_meta.final_func
+ assert '-1' == uda_meta.initial_condition
+ assert 'int' == uda_meta.return_type
self.session.execute("DROP AGGREGATE ks.kind_of_max_agg")
- self.assertEqual(0, len(self._keyspace_meta().aggregates), "expected uda list to be back to zero")
+ assert 0 == len(self._keyspace_meta().aggregates), "expected uda list to be back to zero"
self.session.execute("DROP FUNCTION ks.max_val")
- self.assertEqual(0, len(self._keyspace_meta().functions), "expected udf list to be back to zero")
+ assert 0 == len(self._keyspace_meta().functions), "expected udf list to be back to zero"
- def basic_table_datatype_test(self):
+ def test_basic_table_datatype(self):
establish_basic_datatype_table(self.cluster.version(), self.session)
verify_basic_datatype_table(self.cluster.version(), self.cluster.version(), 'ks', self.session)
- def collection_table_datatype_test(self):
+ def test_collection_table_datatype(self):
establish_collection_datatype_table(self.cluster.version(), self.session)
verify_collection_datatype_table(self.cluster.version(), self.cluster.version(), 'ks', self.session)
- def clustering_order_test(self):
+ def test_clustering_order(self):
establish_clustering_order_table(self.cluster.version(), self.session)
verify_clustering_order_table(self.cluster.version(), self.cluster.version(), 'ks', self.session)
@since("2.0", max_version="3.X") # Compact Storage
- def compact_storage_test(self):
+ def test_compact_storage(self):
establish_compact_storage_table(self.cluster.version(), self.session)
verify_compact_storage_table(self.cluster.version(), self.cluster.version(), 'ks', self.session)
@since("2.0", max_version="3.X") # Compact Storage
- def compact_storage_composite_test(self):
+ def test_compact_storage_composite(self):
establish_compact_storage_composite_table(self.cluster.version(), self.session)
verify_compact_storage_composite_table(self.cluster.version(), self.cluster.version(), 'ks', self.session)
- def nondefault_table_settings_test(self):
+ def test_nondefault_table_settings(self):
establish_nondefault_table_settings(self.cluster.version(), self.session)
verify_nondefault_table_settings(self.cluster.version(), self.cluster.version(), 'ks', self.session)
- def indexes_test(self):
+ def test_indexes(self):
establish_indexes_table(self.cluster.version(), self.session)
verify_indexes_table(self.cluster.version(), self.cluster.version(), 'ks', self.session)
- def durable_writes_test(self):
+ def test_durable_writes(self):
establish_durable_writes_keyspace(self.cluster.version(), self.session)
verify_durable_writes_keyspace(self.cluster.version(), self.cluster.version(), 'ks', self.session)
@since('2.0')
- def static_column_test(self):
+ def test_static_column(self):
establish_static_column_table(self.cluster.version(), self.session)
verify_static_column_table(self.cluster.version(), self.cluster.version(), 'ks', self.session)
@since('2.1')
- def udt_table_test(self):
+ def test_udt_table(self):
establish_udt_table(self.cluster.version(), self.session)
verify_udt_table(self.cluster.version(), self.cluster.version(), 'ks', self.session)
@since('2.2')
- def udf_test(self):
+ def test_udf(self):
establish_udf(self.cluster.version(), self.session)
self.session.cluster.refresh_schema_metadata()
verify_udf(self.cluster.version(), self.cluster.version(), 'ks', self.session)
@since('2.2')
- def uda_test(self):
+ def test_uda(self):
establish_uda(self.cluster.version(), self.session)
self.session.cluster.refresh_schema_metadata()
verify_uda(self.cluster.version(), self.cluster.version(), 'ks', self.session)
http://git-wip-us.apache.org/repos/asf/cassandra-dtest/blob/49b2dda4/schema_test.py
----------------------------------------------------------------------
diff --git a/schema_test.py b/schema_test.py
index 1553adc..8aaea3d 100644
--- a/schema_test.py
+++ b/schema_test.py
@@ -1,15 +1,19 @@
import time
+import pytest
+import logging
from cassandra.concurrent import execute_concurrent_with_args
from tools.assertions import assert_invalid, assert_all, assert_one
-from tools.decorators import since
from dtest import Tester, create_ks
+since = pytest.mark.since
+logger = logging.getLogger(__name__)
+
class TestSchema(Tester):
- def table_alteration_test(self):
+ def test_table_alteration(self):
"""
Tests that table alters return as expected with many sstables at different schema points
"""
@@ -42,16 +46,16 @@ class TestSchema(Tester):
rows = session.execute("select * from tbl_o_churn")
for row in rows:
if row.id < rows_to_insert * 5:
- self.assertEqual(row.c1, 'bbb')
- self.assertIsNone(row.c2)
- self.assertFalse(hasattr(row, 'c0'))
+ assert row.c1 == 'bbb'
+ assert row.c2 is None
+ assert not hasattr(row, 'c0')
else:
- self.assertEqual(row.c1, 'ccc')
- self.assertEqual(row.c2, 'ddd')
- self.assertFalse(hasattr(row, 'c0'))
+ assert row.c1 == 'ccc'
+ assert row.c2 == 'ddd'
+ assert not hasattr(row, 'c0')
@since("2.0", max_version="3.X") # Compact Storage
- def drop_column_compact_test(self):
+ def test_drop_column_compact(self):
session = self.prepare()
session.execute("USE ks")
@@ -59,7 +63,7 @@ class TestSchema(Tester):
assert_invalid(session, "ALTER TABLE cf DROP c1", "Cannot drop columns from a")
- def drop_column_compaction_test(self):
+ def test_drop_column_compaction(self):
session = self.prepare()
session.execute("USE ks")
session.execute("CREATE TABLE cf (key int PRIMARY KEY, c1 int, c2 int)")
@@ -84,7 +88,7 @@ class TestSchema(Tester):
session = self.patient_cql_connection(node)
assert_all(session, "SELECT c1 FROM ks.cf", [[None], [None], [None], [4]], ignore_order=True)
- def drop_column_queries_test(self):
+ def test_drop_column_queries(self):
session = self.prepare()
session.execute("USE ks")
@@ -116,7 +120,7 @@ class TestSchema(Tester):
assert_one(session, "SELECT * FROM cf WHERE c2 = 5", [3, 4, 5])
- def drop_column_and_restart_test(self):
+ def test_drop_column_and_restart(self):
"""
Simply insert data in a table, drop a column involved in the insert and restart the node afterwards.
This ensures that the dropped_columns system table is properly flushed on the alter or the restart
@@ -142,7 +146,7 @@ class TestSchema(Tester):
session.execute("USE ks")
assert_one(session, "SELECT * FROM t", [0, 0])
- def drop_static_column_and_restart_test(self):
+ def test_drop_static_column_and_restart(self):
"""
Dropping a static column caused an sstable corrupt exception after restarting, here
we test that we can drop a static column and restart safely.
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cassandra.apache.org
For additional commands, e-mail: commits-help@cassandra.apache.org