Files
scylladb/test/cql-pytest/run-cassandra
Nadav Har'El 814c4ad4ce cql-pytest: fix run-cassandra for older versions of Cassandra
In older versions of Cassandra (such as 3.11.10 which I tried), the
CQL server is not turned on by default, unless the configuration file
explicitly has "start_native_transport: true" - without it only the
Thrift server is started.

So fix the cql-pytest/run-cassandra to pass this option. It also
works correctly in Cassandra 4.

Signed-off-by: Nadav Har'El <nyh@scylladb.com>
Message-Id: <20210708113423.804980-1-nyh@scylladb.com>
2021-07-08 14:59:09 +03:00

128 lines
6.0 KiB
Python
Executable File

#!/usr/bin/env python3
import sys
import os
import shutil
import run # run.py in this directory
def find_cassandra():
# By default, we assume 'cassandra' is in the user's path. A specific
# cassandra script can be chosen by setting the CASSANDRA variable.
cassandra = os.getenv('CASSANDRA', 'cassandra')
cassandra_path = shutil.which(cassandra)
if cassandra_path is None:
print("Error: Can't find {}. Please set the CASSANDRA environment variable to the path of the Cassandra startup script.".format(cassandra))
exit(1)
return cassandra_path
cassandra = find_cassandra()
def run_cassandra_cmd(pid, dir):
global cassandra
ip = run.pid_to_ip(pid)
# Unfortunately, Cassandra doesn't take command-line parameters. We need
# to write a configuration file, and feed it to Cassandra using
# environment variables. Some of the parameters we did not deliberately
# want to override - they just don't have a default and we must set them.
confdir = os.path.join(dir, 'conf')
os.mkdir(confdir)
with open(os.path.join(confdir, 'cassandra.yaml'), 'w') as f:
print('hints_directory: ' + dir + '/hints\n' +
'data_file_directories:\n - ' + dir + '/data\n' +
'commitlog_directory: ' + dir + '/commitlog\n' +
'saved_caches_directory: ' + dir + '/data/saved_caches\n' +
'commitlog_sync: periodic\n' +
'commitlog_sync_period_in_ms: 10000\n' +
'partitioner: org.apache.cassandra.dht.Murmur3Partitioner\n' +
'endpoint_snitch: SimpleSnitch\n' +
'seed_provider:\n - class_name: org.apache.cassandra.locator.SimpleSeedProvider\n parameters:\n - seeds: "' + ip + '"\n' +
'listen_address: ' + ip + '\n' +
'start_native_transport: true\n' +
'auto_snapshot: false\n' +
'enable_sasi_indexes: true\n' +
'enable_user_defined_functions: true\n' +
'authenticator: PasswordAuthenticator\n' +
'enable_materialized_views: true\n', file=f)
print('Booting Cassandra on ' + ip + ' in ' + dir + '...')
logsdir = os.path.join(dir, 'logs')
os.mkdir(logsdir)
# Cassandra creates some subdirectories on its own, but one it doesn't...
os.mkdir(os.path.join(dir, 'hints'))
env = { 'CASSANDRA_CONF': confdir,
'CASSANDRA_LOG_DIR': logsdir,
'CASSANDRA_INCLUDE': '',
# Unfortunately, Cassandra's JMX cannot listen only on a specific
# interface. To allow tests to use JMX (nodetool), we need to
# have it listen on 0.0.0.0 :-( This is insecure, but arguably
# can be forgiven for test enviroments. The following JVM_OPTS
# configures that:
'JVM_OPTS': '-Dcassandra.jmx.remote.port=7199',
}
# On JVM 11, Cassandra requires a bunch of configuration options in
# conf/jvm11-server.options, or it fails loading classes because of JPMS.
# The following options were copied from Cassandra's jvm11-server.options.
# Note that Cassandra's cassandra.in.sh script requires that the "-"
# appears as the first character of each line:
with open(os.path.join(confdir, 'jvm11-server.options'), 'w') as f:
print('-Djdk.attach.allowAttachSelf=true\n'
'--add-exports java.base/jdk.internal.misc=ALL-UNNAMED\n'
'--add-exports java.base/jdk.internal.ref=ALL-UNNAMED\n'
'--add-exports java.base/sun.nio.ch=ALL-UNNAMED\n'
'--add-exports java.management.rmi/com.sun.jmx.remote.internal.rmi=ALL-UNNAMED\n'
'--add-exports java.rmi/sun.rmi.registry=ALL-UNNAMED\n'
'--add-exports java.rmi/sun.rmi.server=ALL-UNNAMED\n'
'--add-exports java.sql/java.sql=ALL-UNNAMED\n'
'--add-opens java.base/java.lang.module=ALL-UNNAMED\n'
'--add-opens java.base/jdk.internal.loader=ALL-UNNAMED\n'
'--add-opens java.base/jdk.internal.ref=ALL-UNNAMED\n'
'--add-opens java.base/jdk.internal.reflect=ALL-UNNAMED\n'
'--add-opens java.base/jdk.internal.math=ALL-UNNAMED\n'
'--add-opens java.base/jdk.internal.module=ALL-UNNAMED\n'
'--add-opens java.base/jdk.internal.util.jar=ALL-UNNAMED\n'
'--add-opens jdk.management/com.sun.management.internal=ALL-UNNAMED\n',
file=f)
return ([cassandra, '-f'], env)
# Same as run_cassandra_cmd, just use SSL encryption for the CQL port (same
# port number as default - replacing the unencrypted server).
def run_cassandra_ssl_cmd(pid, dir):
(cmd, env) = run_cassandra_cmd(pid, dir)
run.setup_ssl_certificate(dir)
# Cassandra needs a single "keystore" instead of the separate crt and key
# generated by run.setup_ssl_certificate().
os.system(f'openssl pkcs12 -export -in {dir}/scylla.crt -inkey {dir}/scylla.key -password pass:hello -out {dir}/keystore.p12')
with open(os.path.join(dir, 'conf', 'cassandra.yaml'), 'a') as f:
print('client_encryption_options:\n' +
' enabled: true\n' +
' optional: false\n' +
' keystore: ' + dir + '/keystore.p12\n' +
' keystore_password: hello\n' +
' store_type: PKCS12\n',
file=f)
# The command and environment variables to run Cassandra are the same,
return (cmd, env)
print('Cassandra is: ' + cassandra + '.')
if '--ssl' in sys.argv:
cmd = run_cassandra_ssl_cmd
check_cql = run.check_ssl_cql
else:
cmd = run_cassandra_cmd
check_cql = run.check_cql
pid = run.run_with_temporary_dir(cmd)
ip = run.pid_to_ip(pid)
run.wait_for_services(pid, [lambda: check_cql(ip)])
success = run.run_pytest(sys.path[0], ['--host', ip] + sys.argv[1:])
run.summary = 'Cassandra tests pass' if success else 'Cassandra tests failure'
exit(0 if success else 1)
# Note that the run.cleanup_all() function runs now, just like on any exit
# for any reason in this script. It will delete the temporary files and
# announce the failure or success of the test (printing run.summary).