mirror of
https://github.com/scylladb/scylladb.git
synced 2026-05-02 14:15:46 +00:00
This patch adds a nodetool-compatible capability to the cql-pytest
framework. It is *not* meant to be used to test nodetool itself, but
rather to give CQL tests the ability to use nodetool operations -
currently one operation - "nodetool flush".
Use it in a test as:
import nodetool
nodetool.flush(cql, table)
I chose a functional API with parameters ("cql") instead of a fixture
with an implied connection so that in the future we may allow multiple
multiple nodes and this API will allow sending nodetool requests to
different nodes. However, multi-node support is not implemented yet,
nor used in any of the existing tests.
The implementation uses Scylla's REST API if available, or if not, falls
back to using an external "nodetool" command (which can be overridden
using the NODETOOL environment variable). This way, both cql-pytest/run
(Scylla) and cql-pytest/run-cassandra (Cassandra) now correctly support
these nodetool operations, and we still don't need to run JMX to test
Scylla.
The reason We want to support nodetool.flush() is to reproduce bugs that
depend on data reaching disk. We already had such a reproducer in
test_large_cells_rows.py - it too did something similar - but it was
Scylla-only (using only the REST API). Instead of copying such code to
multiple places, we better have a common nodetool.flush() function, as
done in this patch. The test in test_large_cells_rows.py can later be
changed to use the new function.
Signed-off-by: Nadav Har'El <nyh@scylladb.com>
74 lines
3.1 KiB
Python
74 lines
3.1 KiB
Python
# Copyright 2021 ScyllaDB
|
|
#
|
|
# This file is part of Scylla.
|
|
#
|
|
# Scylla is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU Affero General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# Scylla is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Affero General Public License
|
|
# along with Scylla. If not, see <http://www.gnu.org/licenses/>.
|
|
##################################################################
|
|
|
|
# This file provides a few nodetool-compatible commands that may be useful
|
|
# for tests. The intent is *not* to test nodetool itself, but just to
|
|
# use nodetool functionality - e.g., "nodetool flush" when testing CQL.
|
|
#
|
|
# When testing against a locally-running Scylla these functions do not
|
|
# actually use nodetool but rather Scylla's REST API. This simplifies
|
|
# running the test because an external Java process implementing JMX is
|
|
# not needed. However, when the REST API port is not available (i.e, when
|
|
# testing against Cassandra or some remote installation of Scylla) the
|
|
# external "nodetool" command is used, and must be available in the path or
|
|
# chosen with the NODETOOL environment variable.
|
|
|
|
import requests
|
|
import os
|
|
import subprocess
|
|
|
|
# For a "cql" object connected to one node, find the REST API URL
|
|
# with the same node and port 10000.
|
|
# TODO: We may need to change this function or its callers to add proper
|
|
# support for testing on multi-node clusters.
|
|
def rest_api_url(cql):
|
|
return f'http://{cql.cluster.contact_points[0]}:10000'
|
|
|
|
# Check whether the REST API at port 10000 is available - if not we will
|
|
# fall back to using an external "nodetool" program.
|
|
# We only check this once per REST API URL, and cache the decision.
|
|
checked_rest_api = {}
|
|
def has_rest_api(cql):
|
|
url = rest_api_url(cql)
|
|
if not url in checked_rest_api:
|
|
# Scylla's REST API does not have an official "ping" command,
|
|
# so we just list the keyspaces as a (usually) short operation
|
|
try:
|
|
ok = requests.get(f'{url}/column_family/name/keyspace').ok
|
|
except:
|
|
ok = False
|
|
checked_rest_api[url] = ok
|
|
return checked_rest_api[url]
|
|
|
|
|
|
# Run the external "nodetool" executable (can be overridden by the NODETOOL
|
|
# environment variable). Only call this if the REST API doesn't work.
|
|
nodetool_cmd = os.getenv('NODETOOL') or 'nodetool'
|
|
def run_nodetool(cql, *args):
|
|
# TODO: We may need to change this function or its callers to add proper
|
|
# support for testing on multi-node clusters.
|
|
host = cql.cluster.contact_points[0]
|
|
subprocess.run([nodetool_cmd, '-h', host, *args])
|
|
|
|
def flush(cql, table):
|
|
ks, cf = table.split('.')
|
|
if has_rest_api(cql):
|
|
requests.post(f'{rest_api_url(cql)}/storage_service/keyspace_flush/{ks}', params={'cf' : cf})
|
|
else:
|
|
run_nodetool(cql, "flush", ks, cf)
|