Skip to content

Commit 276a243

Browse files
authored
Merge pull request #3609 from IntersectMBO/scripts_types_protocol
refactor: make ScriptsTypes a Protocol
2 parents 5816ddf + f719d19 commit 276a243

2 files changed

Lines changed: 40 additions & 27 deletions

File tree

cardano_node_tests/utils/cluster_nodes.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,10 @@ class ClusterType:
6565

6666
NODES: tp.ClassVar[set[str]] = set()
6767

68+
cluster_scripts: cluster_scripts.ScriptsTypes
69+
6870
def __init__(self) -> None:
6971
self.type = "unknown"
70-
self.cluster_scripts: (
71-
cluster_scripts.ScriptsTypes
72-
| cluster_scripts.TestnetScripts
73-
| cluster_scripts.LocalScripts
74-
) = cluster_scripts.ScriptsTypes()
7572

7673
@property
7774
def testnet_type(self) -> str:

cardano_node_tests/utils/cluster_scripts.py

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -204,50 +204,50 @@ def _reconfigure_local(self, indir: pl.Path, destdir: pl.Path, instance_num: int
204204
self._gen_topology_files(destdir=destdir, addr=addr, nodes=instance_ports.node_ports)
205205

206206

207-
class ScriptsTypes:
208-
"""Generic cluster scripts."""
207+
# Ruff's EM101 rule forbids passing a string literal directly to the exception, and its
208+
# usual fix (assigning to a local variable first) would add a second statement to the
209+
# method bodies. The bodies would then no longer be trivial and type checkers would stop
210+
# treating the protocol methods as abstract. A module-level constant satisfies both
211+
# constraints.
212+
_NOT_IMPLEMENTED_MSG: tp.Final[str] = "Not implemented for this cluster scripts type."
209213

210-
LOCAL: tp.Final[str] = "local"
211-
TESTNET: tp.Final[str] = "testnet"
212214

213-
def __init__(self) -> None:
214-
self.type = "unknown"
215+
class ScriptsTypes(tp.Protocol):
216+
"""Protocol for scripts of a given cluster instance type."""
215217

216218
def get_instance_ports(self, *, instance_num: int) -> cardonnay_local.InstancePorts:
217219
"""Return ports mapping for given cluster instance."""
218-
msg = f"Not implemented for cluster instance type '{self.type}'."
219-
raise NotImplementedError(msg)
220+
raise NotImplementedError(_NOT_IMPLEMENTED_MSG)
220221

221222
def copy_scripts_files(self, *, destdir: ttypes.FileType) -> StartupFiles:
222223
"""Make copy of cluster scripts files.
223224
224225
Testnet files and scripts can be copied and modified by tests before using them.
225226
E.g. we might want to change KES period, pool cost, etc.
226227
"""
227-
msg = f"Not implemented for cluster instance type '{self.type}'."
228-
raise NotImplementedError(msg)
228+
raise NotImplementedError(_NOT_IMPLEMENTED_MSG)
229229

230230
def prepare_scripts_files(
231-
self, *, destdir: ttypes.FileType, instance_num: int, scriptsdir: ttypes.FileType = ""
231+
self,
232+
*,
233+
destdir: ttypes.FileType,
234+
instance_num: int,
235+
scriptsdir: ttypes.FileType | None = None,
232236
) -> cardonnay_local.InstanceFiles:
233237
"""Prepare scripts files for starting and stopping cluster instance."""
234-
msg = f"Not implemented for cluster instance type '{self.type}'."
235-
raise NotImplementedError(msg)
238+
raise NotImplementedError(_NOT_IMPLEMENTED_MSG)
236239

237240
def gen_split_topology_files(
238241
self, *, destdir: ttypes.FileType, instance_num: int, offset: int = 0
239242
) -> None:
240243
"""Generate topology files for split network."""
241-
msg = f"Not implemented for cluster instance type '{self.type}'."
242-
raise NotImplementedError(msg)
244+
raise NotImplementedError(_NOT_IMPLEMENTED_MSG)
243245

244246

245247
class LocalScripts(ScriptsTypes):
246248
"""Scripts for starting local cluster."""
247249

248250
def __init__(self, num_pools: int = -1) -> None:
249-
super().__init__()
250-
self.type = ScriptsTypes.LOCAL
251251
self.num_pools = num_pools
252252
if num_pools == -1:
253253
self.num_pools = configuration.NUM_POOLS
@@ -295,13 +295,17 @@ def copy_scripts_files(self, *, destdir: ttypes.FileType) -> StartupFiles:
295295
)
296296

297297
def prepare_scripts_files(
298-
self, *, destdir: ttypes.FileType, instance_num: int, scriptsdir: ttypes.FileType = ""
298+
self,
299+
*,
300+
destdir: ttypes.FileType,
301+
instance_num: int,
302+
scriptsdir: ttypes.FileType | None = None,
299303
) -> cardonnay_local.InstanceFiles:
300304
"""Prepare scripts files for starting and stopping cluster instance."""
301305
return self.custom_cardonnay_scripts.prepare_scripts_files(
302306
destdir=pl.Path(destdir),
303307
instance_num=instance_num,
304-
scriptsdir=scriptsdir,
308+
scriptsdir=scriptsdir or "",
305309
)
306310

307311
def gen_split_topology_files(
@@ -365,8 +369,6 @@ class TestnetScripts(ScriptsTypes):
365369
BOOTSTRAP_CONF: tp.Final[str] = "testnet_conf"
366370

367371
def __init__(self) -> None:
368-
super().__init__()
369-
self.type = ScriptsTypes.TESTNET
370372
self.scripts_dir = get_testnet_variant_scriptdir2(
371373
testnet_variant=configuration.TESTNET_VARIANT
372374
)
@@ -539,7 +541,11 @@ def _get_bootstrap_conf_dir(self, *, bootstrap_dir: pl.Path) -> pl.Path:
539541
return bootstrap_conf_dir
540542

541543
def prepare_scripts_files(
542-
self, *, destdir: ttypes.FileType, instance_num: int, scriptsdir: ttypes.FileType = ""
544+
self,
545+
*,
546+
destdir: ttypes.FileType,
547+
instance_num: int,
548+
scriptsdir: ttypes.FileType | None = None,
543549
) -> cardonnay_local.InstanceFiles:
544550
"""Prepare scripts files for starting and stopping cluster instance.
545551
@@ -568,3 +574,13 @@ def prepare_scripts_files(
568574
start_script_args=[str(configuration.BOOTSTRAP_DIR)],
569575
dir=destdir,
570576
)
577+
578+
def gen_split_topology_files(
579+
self, *, destdir: ttypes.FileType, instance_num: int, offset: int = 0
580+
) -> None:
581+
"""Generate topology files for split network.
582+
583+
Not supported on testnet, always raises `NotImplementedError`.
584+
"""
585+
msg = "Not implemented for testnet cluster."
586+
raise NotImplementedError(msg)

0 commit comments

Comments
 (0)