Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions modules/ducktests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ You can modify test environments at execution time using global flags injected t
| **AppSpec** | Specifies the class to use for application specifications in Ignite applications. Controls how Ignite applications are configured and started. | ```{"AppSpec": "myapp.services.MyAppSpec"}``` |
| **IgniteTestContext** | Class name for the test context implementation. Allows customization of test context behavior. | ```{"IgniteTestContext": "myapp.context.CustomTestContext"}``` |
| **project** | Project/fork name for version handling (e.g., "ignite", "fork"). Used to distinguish between different Ignite variants. Default is "ignite". | ```{"project": "fork"}``` |
| **mdc_cache_topology_validator** | Whether the MDC tests create their caches with the cache level `MdcTopologyValidator`. Default is True. | ```{"mdc_cache_topology_validator": false}``` |

#### Paths & Directories

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,10 @@
* <ul>
* <li>{@code cacheName} - cache name;</li>
* <li>{@code backups} - number of backups; {@code (backups + 1)} must be divisible by {@code dcsNum};</li>
* <li>{@code topologyValidator} - whether to set the cache level {@link MdcTopologyValidator}, default
* {@code true};</li>
* <li>{@code mainDc} - main data center for the topology validator (2 DC mode); required, and must be
* non-empty, unless {@code datacenters} is given;</li>
* non-empty, unless {@code datacenters} is given or the cache level validator is disabled;</li>
* <li>{@code datacenters} - full DC set for majority-based validation (odd DC count mode),
* takes precedence over {@code mainDc};</li>
* <li>{@code dcsNum} - number of data centers, default 2;</li>
Expand Down Expand Up @@ -82,6 +84,9 @@ public abstract class MdcCacheAwareApplication extends IgniteAwareApplication {
/** */
protected static final int DFLT_PARTITIONS = 512;

/** The cache level topology validator is set unless the parameters say otherwise. */
protected static final boolean DFLT_CACHE_TOP_VALIDATOR = true;

/** */
protected static final CacheAtomicityMode DFLT_ATOMICITY_MODE = ATOMIC;

Expand Down Expand Up @@ -129,6 +134,30 @@ protected <V> CacheConfiguration<Integer, V> mdcCacheConfiguration(JsonNode jNod

int dcsNum = jNode.path("dcsNum").asInt(DFLT_DCS_NUM);

CacheConfiguration<Integer, V> cacheCfg = new CacheConfiguration<Integer, V>()
.setName(cacheName)
.setCacheMode(cacheMode)
.setAtomicityMode(atomicity)
.setWriteSynchronizationMode(writeSync)
.setBackups(backups)
.setReadFromBackup(readFromBackup)
.setAffinity(new RendezvousAffinityFunction()
.setPartitions(partitions)
.setAffinityBackupFilter(new MdcAffinityBackupFilter(dcsNum, backups)));

if (jNode.path("topologyValidator").asBoolean(DFLT_CACHE_TOP_VALIDATOR))
cacheCfg.setTopologyValidator(mdcTopologyValidator(jNode));
else
log.info("Cache level topology validator is disabled [cache=" + cacheName + "]");

return cacheCfg;
}

/**
* @param jNode Parameters.
* @return Cache level topology validator compiled from the application parameters.
*/
private MdcTopologyValidator mdcTopologyValidator(JsonNode jNode) {
MdcTopologyValidator topValidator = new MdcTopologyValidator();

if (jNode.hasNonNull("datacenters")) {
Expand All @@ -147,17 +176,7 @@ protected <V> CacheConfiguration<Integer, V> mdcCacheConfiguration(JsonNode jNod
topValidator.setMainDatacenter(mainDc);
}

return new CacheConfiguration<Integer, V>()
.setName(cacheName)
.setTopologyValidator(topValidator)
.setCacheMode(cacheMode)
.setAtomicityMode(atomicity)
.setWriteSynchronizationMode(writeSync)
.setBackups(backups)
.setReadFromBackup(readFromBackup)
.setAffinity(new RendezvousAffinityFunction()
.setPartitions(partitions)
.setAffinityBackupFilter(new MdcAffinityBackupFilter(dcsNum, backups)));
return topValidator;
}

/**
Expand Down
30 changes: 25 additions & 5 deletions modules/ducktests/tests/ignitetest/services/mdc/mdc_cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@

net.enable_network_partition(DC_1, DC_2)
...

Globals:

mdc_cache_topology_validator - whether the MDC caches are created with the cache level
MdcTopologyValidator, default true.
"""
from typing import Dict, List, Optional, Union

Expand All @@ -45,6 +50,9 @@

IGNITE_STARTUP_TIMEOUT_SEC = 90

# Global: set to false to create the MDC caches without the cache level topology validator.
CACHE_TOP_VALIDATOR_GLOBAL = "mdc_cache_topology_validator"

DATA_CENTER_ATTR = "IGNITE_DATA_CENTER_ID"
IGNITE_SQL_RETRY_TIMEOUT_ATTR = "IGNITE_SQL_RETRY_TIMEOUT"

Expand Down Expand Up @@ -148,6 +156,13 @@ def __init__(self, test, ignite_version: str, srv_per_dc: Union[int, Dict[str, i
# Admissibility checks run on reusable services, so each check needs a unique result prefix.
self._adm_checks = 0

# Cache parameters applied to every cache this fixture creates, unless a call overrides them.
self.cache_defaults = {
"topologyValidator": self.test_context.globals.get(CACHE_TOP_VALIDATOR_GLOBAL, True)
}

self.logger.info(f"MDC cache defaults [{self.cache_defaults}]")

def sync_service_discovery(self):
"""
Points every server service at a discovery SPI covering all DCs.
Expand Down Expand Up @@ -258,12 +273,13 @@ def start_loader(self, dc: str, params: dict, loader: int = 0,
java_class: str = LOAD_APP) -> IgniteApplicationService:
"""
Starts a background load application (runs until stopped). Any exception raised
by the application surfaces in :meth:`stop_loader`.
by the application surfaces in :meth:`stop_loader`. :attr:`cache_defaults` are
merged in.
"""
svc = self.loaders[dc][loader]

svc.java_class_name = java_class
svc.params = params
svc.params = {**self.cache_defaults, **params}

svc.start(clean=self._first_start(svc))

Expand Down Expand Up @@ -292,10 +308,12 @@ def generate_data(self, dc: str, cache_name: str, from_idx: int, to_idx: int, ba
"""
Creates the MDC cache (if absent) and populates keys ``[from_idx, to_idx)``.
Extra cache parameters (``atomicity``, ``writeSync``, ``readFromBackup``,
``partitions``, ...) are passed through to the cache configuration builder.
``partitions``, ...) are passed through to the cache configuration builder, on top
of :attr:`cache_defaults`.
"""
params = {"cacheName": cache_name, "backups": backups, "mainDc": main_dc,
"from": from_idx, "to": to_idx, "sqlMode": sql_mode, **cache_params}
"from": from_idx, "to": to_idx, "sqlMode": sql_mode,
**self.cache_defaults, **cache_params}

return self.run_app(dc, GENERATOR_APP, params)

Expand Down Expand Up @@ -336,8 +354,10 @@ def run_load(self, dc: str, mode: str, cache_name: str, result_prefix: str,
"""
Runs a load burst (see ``MdcContinuousLoadApplication``) and returns the service.
``result_prefix`` must be unique per burst because runner services are reused.
:attr:`cache_defaults` are merged in.
"""
load_params = {"mode": mode, "cacheName": cache_name, "resultPrefix": result_prefix, **params}
load_params = {"mode": mode, "cacheName": cache_name, "resultPrefix": result_prefix,
**self.cache_defaults, **params}

return self.run_app(dc, LOAD_APP, load_params, runner=runner)

Expand Down