Skip to content

Commit 7d11676

Browse files
fix(gemini-cmd): broken gemini commands on upgrades
When gemini_thread.py was refactored, every command in test-cases/gemini was refactored to use the new model of declaring the flags. But it was not anticipated that there were more places where gemini was used e.g. test-cases/cdc and test-cases/upgrades Signed-off-by: Dusan Malusev <[email protected]>
1 parent 1d78d29 commit 7d11676

File tree

9 files changed

+173
-62
lines changed

9 files changed

+173
-62
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
gemini:
2-
image: scylladb/gemini:1.8.9
2+
image: scylladb/gemini:1.8.10

sdcm/gemini_thread.py

+39-42
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
from sdcm.stress_thread import DockerBasedStressThread
2525
from sdcm.utils.docker_remote import RemoteDocker
2626

27-
2827
LOGGER = logging.getLogger(__name__)
2928

3029

@@ -59,7 +58,6 @@ def run(self):
5958

6059

6160
class GeminiStressThread(DockerBasedStressThread): # pylint: disable=too-many-instance-attributes
62-
6361
DOCKER_IMAGE_PARAM_NAME = "stress_image.gemini"
6462

6563
def __init__(self, test_cluster, oracle_cluster, loaders, stress_cmd, timeout=None, params=None): # pylint: disable=too-many-arguments
@@ -105,9 +103,9 @@ def __init__(self, test_cluster, oracle_cluster, loaders, stress_cmd, timeout=No
105103
self.gemini_result_file = f"gemini_result_{self.unique_id}.log"
106104

107105
def _generate_gemini_command(self):
108-
seed = self.params.get('gemini_seed') or random.randint(1, 100)
109-
table_options = self.params.get('gemini_table_options')
110-
log_statements = self.params.get('gemini_log_cql_statements') or False
106+
seed = self.params.get("gemini_seed") or random.randint(1, 100)
107+
table_options = self.params.get("gemini_table_options")
108+
log_statements = self.params.get("gemini_log_cql_statements") or False
111109

112110
test_nodes = ",".join(self.test_cluster.get_node_cql_ips())
113111
oracle_nodes = ",".join(self.oracle_cluster.get_node_cql_ips())
@@ -119,7 +117,7 @@ def _generate_gemini_command(self):
119117
--seed={seed} \
120118
--schema-seed={seed} \
121119
--profiling-port=6060 \
122-
--bind=0.0.0.0:2121 \
120+
--bind=0.0.0.0:2112 \
123121
--outfile=/{self.gemini_result_file} \
124122
--replication-strategy=\"{{'class': 'NetworkTopologyStrategy', 'replication_factor': '3'}}\" \
125123
--oracle-replication-strategy=\"{{'class': 'NetworkTopologyStrategy', 'replication_factor': '1'}}\" "
@@ -130,16 +128,16 @@ def _generate_gemini_command(self):
130128

131129
credentials = self.loader_set.get_db_auth()
132130

133-
if credentials and '--test-username' not in cmd:
131+
if credentials and "--test-username" not in cmd:
134132
cmd += f"--test-username={credentials[0]} \
135133
--test-password={credentials[1]} \
136134
--oracle-username={credentials[0]} \
137135
--oracle-password={credentials[1]} "
138136

139137
if table_options:
140-
cmd += " ".join([f"--table-options=\"{table_opt}\"" for table_opt in table_options])
138+
cmd += " ".join([f'--table-options="{table_opt}"' for table_opt in table_options])
141139

142-
stress_cmd = self.stress_cmd.replace('\n', ' ').strip()
140+
stress_cmd = self.stress_cmd.replace("\n", " ").strip()
143141

144142
for key, value in self.gemini_default_flags.items():
145143
if not key in stress_cmd:
@@ -156,35 +154,35 @@ def _run_stress(self, loader, loader_idx, cpu_idx):
156154
docker = cleanup_context = RemoteDocker(
157155
loader,
158156
self.docker_image_name,
159-
extra_docker_opts=f'--cpuset-cpus="{cpu_idx}"' if self.stress_num > 1 else ""
160-
'--label shell_marker={self.shell_marker}'
161-
'--network=host '
162-
'--security-opt seccomp=unconfined '
157+
extra_docker_opts=f'--cpuset-cpus="{cpu_idx}" '
158+
if self.stress_num > 1
159+
else ""
160+
"--network=host "
161+
"--security-opt seccomp=unconfined "
163162
'--entrypoint="" '
164-
f'-v $HOME/{self.gemini_result_file}:/{self.gemini_result_file} '
165-
f'-v $HOME/{self.gemini_test_statements_file}:/{self.gemini_test_statements_file} '
166-
f'-v $HOME/{self.gemini_oracle_statements_file}:/{self.gemini_oracle_statements_file} '
163+
f"--label shell_marker={self.shell_marker} "
164+
f"-v $HOME/{self.gemini_result_file}:/{self.gemini_result_file} "
165+
f"-v $HOME/{self.gemini_test_statements_file}:/{self.gemini_test_statements_file} "
166+
f"-v $HOME/{self.gemini_oracle_statements_file}:/{self.gemini_oracle_statements_file} ",
167167
)
168168

169169
if not os.path.exists(loader.logdir):
170170
os.makedirs(loader.logdir, exist_ok=True)
171-
log_file_name = os.path.join(loader.logdir, 'gemini-l%s-c%s-%s.log' %
172-
(loader_idx, cpu_idx, uuid.uuid4()))
173-
LOGGER.debug('gemini local log: %s', log_file_name)
171+
log_file_name = os.path.join(loader.logdir, "gemini-l%s-c%s-%s.log" % (loader_idx, cpu_idx, uuid.uuid4()))
172+
LOGGER.debug("gemini local log: %s", log_file_name)
174173

175174
gemini_cmd = self._generate_gemini_command()
176-
with cleanup_context, \
177-
GeminiEventsPublisher(node=loader, gemini_log_filename=log_file_name) as publisher, \
178-
GeminiStressEvent(node=loader, cmd=gemini_cmd, log_file_name=log_file_name) as gemini_stress_event:
175+
with cleanup_context, GeminiEventsPublisher(node=loader, gemini_log_filename=log_file_name) as publisher, GeminiStressEvent(node=loader, cmd=gemini_cmd, log_file_name=log_file_name) as gemini_stress_event:
179176
try:
180177
publisher.event_id = gemini_stress_event.event_id
181178
gemini_stress_event.log_file_name = log_file_name
182-
result = docker.run(cmd=gemini_cmd,
183-
timeout=self.timeout,
184-
ignore_status=False,
185-
log_file=log_file_name,
186-
retry=0,
187-
)
179+
result = docker.run(
180+
cmd=gemini_cmd,
181+
timeout=self.timeout,
182+
ignore_status=False,
183+
log_file=log_file_name,
184+
retry=0,
185+
)
188186
# sleep to gather all latest log messages
189187
time.sleep(5)
190188
except Exception as details: # pylint: disable=broad-except
@@ -227,34 +225,33 @@ def get_gemini_results(self):
227225

228226
@staticmethod
229227
def verify_gemini_results(results):
230-
231-
stats = {'results': [], 'errors': {}}
228+
stats = {"results": [], "errors": {}}
232229
if not results:
233-
LOGGER.error('Gemini results are not found')
234-
stats['status'] = 'FAILED'
230+
LOGGER.error("Gemini results are not found")
231+
stats["status"] = "FAILED"
235232
else:
236233
for res in results:
237-
stats['results'].append(res)
238-
for err_type in ['write_errors', 'read_errors', 'errors']:
234+
stats["results"].append(res)
235+
for err_type in ["write_errors", "read_errors", "errors"]:
239236
if res.get(err_type, None):
240237
LOGGER.error("Gemini {} errors: {}".format(err_type, res[err_type]))
241-
stats['status'] = 'FAILED'
242-
stats['errors'][err_type] = res[err_type]
243-
if not stats.get('status'):
244-
stats['status'] = "PASSED"
238+
stats["status"] = "FAILED"
239+
stats["errors"][err_type] = res[err_type]
240+
if not stats.get("status"):
241+
stats["status"] = "PASSED"
245242

246243
return stats
247244

248245
@staticmethod
249246
def _parse_gemini_summary_json(json_str):
250-
results = {'result': {}}
247+
results = {"result": {}}
251248
try:
252249
results = json.loads(json_str)
253250

254251
except Exception as details: # pylint: disable=broad-except
255252
LOGGER.error("Invalid json document {}".format(details))
256253

257-
return results.get('result')
254+
return results.get("result")
258255

259256
@staticmethod
260257
def _parse_gemini_summary(lines):
@@ -263,7 +260,7 @@ def _parse_gemini_summary(lines):
263260

264261
for line in lines:
265262
line.strip()
266-
if 'Results:' in line:
263+
if "Results:" in line:
267264
enable_parse = True
268265
continue
269266
if "run completed" in line:
@@ -272,7 +269,7 @@ def _parse_gemini_summary(lines):
272269
if not enable_parse:
273270
continue
274271

275-
split_idx = line.index(':')
272+
split_idx = line.index(":")
276273
key = line[:split_idx].strip()
277274
value = line[split_idx + 1:].split()[0]
278275
results[key] = int(value)

test-cases/cdc/cdc-15m-replication-gemini.yaml

+11-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,17 @@ nemesis_interval: 1
2020
# Required by the nemesis:
2121
extra_network_interface: true
2222

23-
gemini_cmd: "gemini -d --duration 15m --warmup 0s -c 5 -m write --non-interactive --cql-features basic --max-mutation-retries 100 --max-mutation-retries-backoff 100ms --replication-strategy \"{'class': 'NetworkTopologyStrategy', 'replication_factor': '3'}\" --table-options \"cdc = {'enabled': true}\""
23+
gemini_cmd: |
24+
--duration 15m
25+
--warmup 0s
26+
--concurrency 5
27+
--mode write
28+
--cql-features basic
29+
--max-mutation-retries 100
30+
--max-mutation-retries-backoff 100ms
31+
32+
gemini_table_options:
33+
- "cdc={'enabled': true}"
2434

2535

2636
# Required by SCT, although not used:

test-cases/cdc/cdc-15m-replication-postimage.yaml

+11-2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,17 @@ extra_network_interface: true
2222

2323
# Note: for preimage and postimage we use 1 thread because there is no sensible way
2424
# to test pre/post-images with concurrent writes happening to a single row.
25-
gemini_cmd: "gemini -d --duration 15m --warmup 0s -c 1 -m write --non-interactive --cql-features basic --max-mutation-retries 100 --max-mutation-retries-backoff 100ms --replication-strategy \"{'class': 'NetworkTopologyStrategy', 'replication_factor': '3'}\" --table-options \"cdc = {'enabled': true, 'postimage': true}\""
26-
25+
gemini_cmd: |
26+
--duration 15m
27+
--warmup 0s
28+
--concurrency 1
29+
--mode write
30+
--cql-features basic
31+
--max-mutation-retries 100
32+
--max-mutation-retries-backoff 100ms
33+
34+
gemini_table_options:
35+
- "cdc = {'enabled': true, 'postimage': true}"
2736

2837
# Required by SCT, although not used:
2938
gemini_schema_url: 'https://s3.amazonaws.com/scylla-gemini/Binaries/schema.json'

test-cases/cdc/cdc-15m-replication-preimage.yaml

+11-2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,17 @@ extra_network_interface: true
2222

2323
# Note: for preimage and postimage we use 1 thread because there is no sensible way
2424
# to test pre/post-images with concurrent writes happening to a single row.
25-
gemini_cmd: "gemini -d --duration 15m --warmup 0s -c 1 -m write --non-interactive --cql-features basic --max-mutation-retries 100 --max-mutation-retries-backoff 100ms --replication-strategy \"{'class': 'NetworkTopologyStrategy', 'replication_factor': '3'}\" --table-options \"cdc = {'enabled': true, 'preimage': 'full'}\""
26-
25+
gemini_cmd: |
26+
--duration 15m
27+
--warmup 0s
28+
--concurrency 1
29+
--mode write
30+
--cql-features basic
31+
--max-mutation-retries 100
32+
--max-mutation-retries-backoff 100ms
33+
34+
gemini_table_options:
35+
- "cdc = {'enabled': true, 'preimage': 'full'}"
2736

2837
# Required by SCT, although not used:
2938
gemini_schema_url: 'https://s3.amazonaws.com/scylla-gemini/Binaries/schema.json'

test-cases/cdc/cdc-replication-longevity.yaml

+12-2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,18 @@ nemesis_interval: 5
1919

2020
extra_network_interface: True
2121

22-
gemini_cmd: "gemini --duration 30m --warmup 0s -c 4 -m write --non-interactive --cql-features basic --max-mutation-retries 100 --max-mutation-retries-backoff 100ms --replication-strategy \"{'class': 'NetworkTopologyStrategy', 'replication_factor': '3'}\" --table-options \"cdc = {'enabled': true, 'ttl': 0}\" --use-server-timestamps --test-host-selection-policy token-aware"
23-
22+
gemini_cmd: |
23+
--duration 30m
24+
--warmup 0s
25+
--concurrency 4
26+
--mode write
27+
--cql-features basic
28+
--max-mutation-retries 100
29+
--max-mutation-retries-backoff 100ms
30+
--use-server-timestamps
31+
32+
gemini_table_options:
33+
- "cdc = {'enabled': true, 'ttl': 0}"
2434

2535
# Required by SCT, although not used:
2636
gemini_schema_url: 'https://s3.amazonaws.com/scylla-gemini/Binaries/schema.json'

test-cases/upgrades/rolling-upgrade.yaml

+12-6
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,20 @@ authenticator_password: 'cassandra'
3030

3131
use_mgmt: false
3232

33-
gemini_cmd: "gemini -d --duration 2h \
34-
-c 10 -m write -f --non-interactive --cql-features normal \
35-
--max-mutation-retries 5 --max-mutation-retries-backoff 500ms \
36-
--async-objects-stabilization-attempts 5 --async-objects-stabilization-backoff 500ms \
37-
--replication-strategy \"{'class': 'NetworkTopologyStrategy', 'replication_factor': '3'}\" \
38-
--table-options \"cdc={'enabled': true}\" --test-username cassandra --test-password cassandra"
33+
gemini_cmd: |
34+
--duration 2h
35+
--concurrency 10
36+
--mode write
37+
--max-mutation-retries 5
38+
--max-mutation-retries-backoff 500ms
39+
--async-objects-stabilization-attempts 5
40+
--async-objects-stabilization-backoff 500ms
41+
3942
gemini_seed: 66
4043

44+
gemini_table_options:
45+
- "cdc={'enabled':true}"
46+
4147
gemini_schema_url: 'https://s3.amazonaws.com/scylla-gemini/Binaries/schema.json' # currently is not used
4248

4349
use_preinstalled_scylla: false
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
test_duration: 900
2+
3+
user_prefix: 'cdc-replication-longevity'
4+
db_type: mixed_scylla
5+
6+
n_db_nodes: 3
7+
instance_type_db: 'i4i.large'
8+
9+
n_test_oracle_db_nodes: 1
10+
instance_type_db_oracle: 'i3.large'
11+
12+
n_loaders: 1
13+
instance_type_loader: 'c6i.large'
14+
15+
n_monitor_nodes: 1
16+
17+
nemesis_class_name: 'CategoricalMonkey'
18+
nemesis_interval: 5
19+
20+
gemini_cmd: |
21+
--duration 30m
22+
--warmup 0s
23+
--concurrency 4
24+
--mode write
25+
--cql-features basic
26+
--max-mutation-retries 100
27+
--max-mutation-retries-backoff 100ms
28+
--use-server-timestamps
29+
--test-host-selection-policy token-aware
30+
31+
gemini_table_options:
32+
- "cdc={'enabled':true,'ttl':0}"
33+
34+
# Required by SCT, although not used:
35+
gemini_schema_url: 'https://s3.amazonaws.com/scylla-gemini/Binaries/schema.json'
36+
37+
scylla_network_config:
38+
- address: listen_address # Address Scylla listens for connections from other nodes. See storage_port and ssl_storage_ports.
39+
ip_type: ipv4
40+
public: false
41+
listen_all: true # Should be True when multiple interfaces - Scylla should be listening on all interfaces
42+
use_dns: false
43+
nic: 1
44+
- address: rpc_address # Address on which Scylla is going to expect Thrift and CQL client connections.
45+
ip_type: ipv4
46+
public: false
47+
listen_all: true # Should be True when multiple interfaces - Scylla should be listening on all interfaces
48+
use_dns: false
49+
nic: 1
50+
- address: broadcast_rpc_address # Address that is broadcasted to tell the clients to connect to. Related to rpc_address.
51+
ip_type: ipv4
52+
public: false # Should be False when multiple interfaces
53+
use_dns: false
54+
nic: 1
55+
- address: broadcast_address # Address that is broadcasted to tell other Scylla nodes to connect to. Related to listen_address above.
56+
ip_type: ipv4
57+
public: false # Should be False when multiple interfaces
58+
use_dns: false
59+
nic: 1 # If ipv4 and public is True it has to be primary network interface (device index is 0)
60+
- address: test_communication # Type of IP used to connect to machine instances
61+
ip_type: ipv4
62+
public: false
63+
use_dns: false
64+
nic: 0 # If ipv4 and public is True it has to be primary network interface (device index is 0)

unit_tests/test_data/test_scylla_yaml_builders/rolling-upgrade.yaml

+12-6
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,17 @@ authenticator_password: 'cassandra'
3737

3838
use_mgmt: false
3939

40-
gemini_cmd: "gemini -d --duration 2h \
41-
-c 10 -m write -f --non-interactive --cql-features normal \
42-
--max-mutation-retries 5 --max-mutation-retries-backoff 500ms \
43-
--async-objects-stabilization-attempts 5 --async-objects-stabilization-backoff 500ms \
44-
--replication-strategy \"{'class': 'NetworkTopologyStrategy', 'replication_factor': '3'}\" \
45-
--table-options \"cdc={'enabled': true}\" --test-username cassandra --test-password cassandra"
40+
gemini_cmd: |
41+
--duration 2h
42+
--concurrency 10
43+
--mode write
44+
--cql-features normal
45+
--max-mutation-retries 5
46+
--max-mutation-retries-backoff 500ms
47+
--async-objects-stabilization-attempts 5
48+
--async-objects-stabilization-backoff 500ms
49+
50+
gemini_table_options:
51+
- "cdc={'enabled': true}"
4652

4753
gemini_schema_url: 'https://s3.amazonaws.com/scylla-gemini/Binaries/schema.json' # currently is not used

0 commit comments

Comments
 (0)