mirror of
https://github.com/scylladb/scylladb.git
synced 2026-04-25 19:10:42 +00:00
Add tests for Streams, when table uses tablets underneath. One test verifies filtering using CHILD_SHARDS feature. Other one makes sure we get read all data while the table undergoes tablet count change. Add `--tablet-load-stats-refresh-interval-in-seconds=1` to `alternator/run` script, as otherwise newly added tests will fail. The setting changes how often scylla refreshes tablet metadata. This can't be done using `scylla_config_temporary`, as 1) default is 60 seconds 2) scylla will wait full timeout (60s) to read configuration variable again.
190 lines
8.1 KiB
Python
Executable File
190 lines
8.1 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# Use the run.py library from ../cqlpy:
|
|
import sys
|
|
sys.path.insert(1, sys.path[0] + '/../cqlpy')
|
|
import run
|
|
|
|
import os
|
|
import requests
|
|
import glob
|
|
|
|
# When tests are to be run against AWS (the "--aws" option), it is not
|
|
# necessary to start Scylla at all. All we need to do is to run pytest.
|
|
if '--aws' in sys.argv:
|
|
success = run.run_pytest(sys.path[0], ['-o', 'xfail_strict=false'] + sys.argv[1:])
|
|
exit(0 if success else 1)
|
|
|
|
# check_alternator() below uses verify=False to accept self-signed SSL
|
|
# certificates but then we get scary warnings. This trick disables them:
|
|
import urllib3
|
|
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
|
|
|
|
|
# If the first option is "--release", download that release (see
|
|
# fetch_scylla.py for supported release numbers), and use that.
|
|
# The downloaded Scylla will be cached in the directory build/<release>,
|
|
# where <release> is the specific release downloaded - E.g., if the user
|
|
# asks "--release 2022.1" and the downloaded release is 2022.1.9, it
|
|
# will be stored in build/2022.1.9.
|
|
if len(sys.argv) > 1 and sys.argv[1] == '--release':
|
|
release = sys.argv[2]
|
|
exe = run.download_precompiled_scylla(release)
|
|
run_scylla_cmd = lambda pid, dir: run.run_precompiled_scylla_cmd(exe, pid, dir)
|
|
sys.argv = sys.argv[0:1] + sys.argv[3:]
|
|
os.environ['SCYLLA'] = exe # so find_scylla() prints the right one
|
|
else:
|
|
run_scylla_cmd = run.run_scylla_cmd
|
|
|
|
print('Scylla is: ' + run.find_scylla() + '.')
|
|
|
|
extra_scylla_options = []
|
|
remove_scylla_options = []
|
|
|
|
# If the "--vnodes" option is given, drop the "tablets" experimental
|
|
# feature (turned on in run.py) so that all tests will be run with the
|
|
# old vnode-based replication instead of tablets. This option only has
|
|
# temporary usefulness, and should eventually be removed.
|
|
if '--vnodes' in sys.argv:
|
|
sys.argv.remove('--vnodes')
|
|
remove_scylla_options.append('--enable-tablets=true')
|
|
# Tablets are now enabled by default on some releases, it is not enough to remove the enable above.
|
|
extra_scylla_options.append('--enable-tablets=false')
|
|
|
|
if "-h" in sys.argv or "--help" in sys.argv:
|
|
run.run_pytest(sys.path[0], sys.argv)
|
|
exit(0)
|
|
|
|
# run_alternator_cmd runs the same as run_scylla_cmd with *additional*
|
|
# parameters, so in particular both CQL and Alternator will be enabled.
|
|
# This is useful for us because we need CQL to setup authentication.
|
|
def run_alternator_cmd(pid, dir):
|
|
(cmd, env) = run_scylla_cmd(pid, dir)
|
|
ip = run.pid_to_ip(pid)
|
|
cmd += [
|
|
'--alternator-address', ip,
|
|
'--alternator-enforce-authorization', '1',
|
|
'--alternator-write-isolation', 'only_rmw_uses_lwt',
|
|
'--alternator-streams-time-window-s', '0',
|
|
'--alternator-timeout-in-ms', '30000',
|
|
# no longer needed here because it's defined in test/cqlpy/run.py
|
|
# now that this parameter is used also by CQL's per-row TTL.
|
|
#'--alternator-ttl-period-in-seconds', '0.5',
|
|
'--alternator-allow-system-table-write=1',
|
|
# Allow testing experimental features. Following issue #9467, we need
|
|
# to add here specific experimental features as they are introduced.
|
|
# We only list here Alternator-specific experimental features - CQL
|
|
# ones are listed in test/cqlpy/run.py.
|
|
'--experimental-features=alternator-streams',
|
|
# this is required by test_streams.py test_parent_filtering and test_get_records_with_alternating_tablets_count
|
|
# setting the value using scylla_config_temporary won't work, because the value is read
|
|
# at the start and then periodically with `tablet-load-stats-refresh-interval-in-seconds`
|
|
# interval, which by default is 60 seconds.
|
|
'--tablet-load-stats-refresh-interval-in-seconds=1',
|
|
]
|
|
if '--https' in sys.argv:
|
|
run.setup_ssl_certificate(dir)
|
|
cmd += ['--alternator-https-port', '8043',
|
|
'--alternator-encryption-options', f'keyfile={dir}/scylla.key',
|
|
'--alternator-encryption-options', f'certificate={dir}/scylla.crt',
|
|
]
|
|
else:
|
|
cmd += ['--alternator-port', '8000']
|
|
if '--vs' in sys.argv:
|
|
cmd += ['--vector-store-primary-uri', f'http://{ip}:6080']
|
|
cmd += extra_scylla_options
|
|
|
|
for i in remove_scylla_options:
|
|
cmd.remove(i)
|
|
|
|
# Unfortunately, earlier Scylla versions required different command line
|
|
# options to run, so for some old versions we need to drop some of the
|
|
# command line options added above, or add more options. In cqlpy/run.py's
|
|
# run_precompiled_scylla_cmd we already do this for most Scylla options,
|
|
# but here we just need to take care of the Alternator-specific options
|
|
# that we added here and were different in older versions.
|
|
if 'release' in globals():
|
|
version = release.split('~')[0].split('.')
|
|
major = [int(version[0]), int(version[1])]
|
|
print(major)
|
|
if major < [2025,4]:
|
|
cmd.remove('--alternator-allow-system-table-write=1')
|
|
|
|
return (cmd, env)
|
|
|
|
pid = run.run_with_temporary_dir(run_alternator_cmd)
|
|
ip = run.pid_to_ip(pid)
|
|
|
|
if '--https' in sys.argv:
|
|
alternator_url=f"https://{ip}:8043"
|
|
else:
|
|
alternator_url=f"http://{ip}:8000"
|
|
|
|
# If the "--vs" option is given, also run the vector store process.
|
|
# The vector store is run in its own temporary directory, but runs
|
|
# on the same IP address as Scylla (otherwise, the first of the two
|
|
# which we will run will not know where to find the second).
|
|
def run_vector_store_cmd(pid, dir):
|
|
global ip # same IP as Scylla, see comment above
|
|
print('Booting Vector Store on ' + ip + ' in ' + dir + '...')
|
|
with open(f'{dir}/.password', 'w') as f:
|
|
print('cassandra', file=f)
|
|
env = {
|
|
'VECTOR_STORE_URI': f'{ip}:6080',
|
|
'VECTOR_STORE_SCYLLADB_URI': f'{ip}:9042',
|
|
'VECTOR_STORE_SCYLLADB_USERNAME': 'cassandra',
|
|
'VECTOR_STORE_SCYLLADB_PASSWORD_FILE': f'{dir}/.password',
|
|
}
|
|
global vector_store_executable # set by the code below
|
|
cmd = [
|
|
vector_store_executable
|
|
]
|
|
return (cmd, env)
|
|
if '--vs' in sys.argv:
|
|
sys.argv.remove('--vs')
|
|
# Find the vector-store executable. We look for it in the vector-store/
|
|
# directory next to the Scylla working directory taking the newest built
|
|
# executable, but it can also be specified by the user by setting the
|
|
# VECTOR_STORE environment variable to the path of if os.getenv('SCYLLA'):
|
|
global vector_store_executable
|
|
if os.getenv('VECTOR_STORE'):
|
|
vector_store_executable = os.path.abspath(os.getenv('VECTOR_STORE'))
|
|
else:
|
|
vector_store_dir = os.path.join(os.path.dirname(run.source_path), 'vector-store')
|
|
vector_stores = glob.glob(os.path.join(vector_store_dir, 'target/*/vector-store'))
|
|
if not vector_stores:
|
|
print(f"Can't find a compiled Vector Store in {vector_store_dir}.\nPlease build Vector Store or set VECTOR_STORE to the path of a Vector Store executable.")
|
|
exit(1)
|
|
vector_store_executable = max(vector_stores, key=os.path.getmtime)
|
|
if not os.access(vector_store_executable, os.X_OK):
|
|
print(f"Cannot execute '{vector_store_executable}'.\nPlease set VECTOR_STORE to the path of a Vector Store executable.")
|
|
exit(1)
|
|
print(f"Vector Store is: {vector_store_executable}.")
|
|
run.run_with_temporary_dir(run_vector_store_cmd)
|
|
|
|
|
|
# Wait for both CQL and Alternator APIs to become responsive. We obviously
|
|
# need the Alternator API to test Alternator, but currently we also need
|
|
# CQL for setting up authentication.
|
|
def check_alternator(url):
|
|
try:
|
|
requests.get(url, verify=False)
|
|
except requests.ConnectionError:
|
|
raise run.NotYetUp
|
|
# Any other exception may indicate a problem, and is passed to the caller.
|
|
|
|
run.wait_for_services(pid, [
|
|
lambda: run.check_cql(ip),
|
|
lambda: check_alternator(alternator_url),
|
|
])
|
|
|
|
# Finally run pytest:
|
|
success = run.run_pytest(sys.path[0], ['--url', alternator_url] + sys.argv[1:])
|
|
|
|
run.summary = 'Alternator tests pass' if success else 'Alternator 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).
|