diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index be3570828..1952e496b 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -23,7 +23,7 @@ on: jobs: analyze: name: Analyze - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 permissions: actions: read contents: read diff --git a/adapter-cqld4/src/main/java/io/nosqlbench/adapter/cqld4/Cqld4DriverAdapter.java b/adapter-cqld4/src/main/java/io/nosqlbench/adapter/cqld4/Cqld4DriverAdapter.java index d8aa80c30..9a23965d4 100644 --- a/adapter-cqld4/src/main/java/io/nosqlbench/adapter/cqld4/Cqld4DriverAdapter.java +++ b/adapter-cqld4/src/main/java/io/nosqlbench/adapter/cqld4/Cqld4DriverAdapter.java @@ -17,14 +17,14 @@ package io.nosqlbench.adapter.cqld4; import io.nosqlbench.adapter.cqld4.opmappers.Cqld4CoreOpMapper; +import io.nosqlbench.api.config.standard.NBConfigModel; +import io.nosqlbench.api.config.standard.NBConfiguration; import io.nosqlbench.engine.api.activityimpl.OpMapper; import io.nosqlbench.engine.api.activityimpl.uniform.BaseDriverAdapter; import io.nosqlbench.engine.api.activityimpl.uniform.DriverAdapter; import io.nosqlbench.engine.api.activityimpl.uniform.DriverSpaceCache; import io.nosqlbench.engine.api.activityimpl.uniform.flowtypes.Op; import io.nosqlbench.nb.annotations.Service; -import io.nosqlbench.api.config.standard.NBConfigModel; -import io.nosqlbench.api.config.standard.NBConfiguration; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; diff --git a/adapter-cqld4/src/main/java/io/nosqlbench/adapter/cqld4/Cqld4Space.java b/adapter-cqld4/src/main/java/io/nosqlbench/adapter/cqld4/Cqld4Space.java index a7aba6c0c..cf9d3d694 100644 --- a/adapter-cqld4/src/main/java/io/nosqlbench/adapter/cqld4/Cqld4Space.java +++ b/adapter-cqld4/src/main/java/io/nosqlbench/adapter/cqld4/Cqld4Space.java @@ -28,9 +28,9 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import io.nosqlbench.adapter.cqld4.optionhelpers.OptionHelpers; import io.nosqlbench.api.config.standard.*; -import io.nosqlbench.api.engine.util.SSLKsFactory; import io.nosqlbench.api.content.Content; import io.nosqlbench.api.content.NBIO; +import io.nosqlbench.api.engine.util.SSLKsFactory; import io.nosqlbench.api.errors.BasicError; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -44,7 +44,7 @@ import java.nio.file.Paths; import java.util.*; import java.util.stream.Collectors; -public class Cqld4Space { +public class Cqld4Space implements AutoCloseable { private final static Logger logger = LogManager.getLogger(Cqld4Space.class); private final String space; @@ -282,8 +282,8 @@ public class Cqld4Space { public static NBConfigModel getConfigModel() { return ConfigModel.of(Cqld4Space.class) .add(Param.optional("localdc")) - .add(Param.optional(List.of("secureconnectbundle","scb"))) - .add(Param.optional(List.of("hosts","host"))) + .add(Param.optional(List.of("secureconnectbundle", "scb"))) + .add(Param.optional(List.of("hosts", "host"))) .add(Param.optional("driverconfig", String.class)) .add(Param.optional("username", String.class, "user name (see also password and passfile)")) .add(Param.optional("userfile", String.class, "file to load the username from")) @@ -299,4 +299,13 @@ public class Cqld4Space { } + @Override + public void close() { + try { + this.getSession().close(); + } catch (Exception e) { + logger.warn("auto-closeable cql session threw exception in cql space(" + this.space + "): " + e); + throw e; + } + } } diff --git a/adapter-diag/src/main/java/io/nosqlbench/adapter/diag/DiagDriverAdapter.java b/adapter-diag/src/main/java/io/nosqlbench/adapter/diag/DiagDriverAdapter.java index a599e2242..037b6fb05 100644 --- a/adapter-diag/src/main/java/io/nosqlbench/adapter/diag/DiagDriverAdapter.java +++ b/adapter-diag/src/main/java/io/nosqlbench/adapter/diag/DiagDriverAdapter.java @@ -51,7 +51,7 @@ public class DiagDriverAdapter extends BaseDriverAdapter impl @Override public synchronized OpMapper getOpMapper() { if (this.mapper == null) { - this.mapper = new DiagOpMapper(this, getSpaceCache()); + this.mapper = new DiagOpMapper(this); } return this.mapper; } diff --git a/adapter-diag/src/main/java/io/nosqlbench/adapter/diag/DiagOp.java b/adapter-diag/src/main/java/io/nosqlbench/adapter/diag/DiagOp.java index 63f7ef3ab..cf6d2f2b7 100644 --- a/adapter-diag/src/main/java/io/nosqlbench/adapter/diag/DiagOp.java +++ b/adapter-diag/src/main/java/io/nosqlbench/adapter/diag/DiagOp.java @@ -28,9 +28,11 @@ public class DiagOp implements CycleOp { private final static Logger logger = LogManager.getLogger(DiagOp.class); private final List mutators; + private final DiagSpace space; - public DiagOp(List mutators) { + public DiagOp(DiagSpace space, List mutators) { this.mutators = mutators; + this.space = space; } @Override diff --git a/adapter-diag/src/main/java/io/nosqlbench/adapter/diag/DiagOpDispenser.java b/adapter-diag/src/main/java/io/nosqlbench/adapter/diag/DiagOpDispenser.java index 0ff2ad2cc..87ad8e76f 100644 --- a/adapter-diag/src/main/java/io/nosqlbench/adapter/diag/DiagOpDispenser.java +++ b/adapter-diag/src/main/java/io/nosqlbench/adapter/diag/DiagOpDispenser.java @@ -17,14 +17,13 @@ package io.nosqlbench.adapter.diag; import io.nosqlbench.adapter.diag.optasks.DiagTask; -import io.nosqlbench.engine.api.activityapi.ratelimits.RateLimiter; -import io.nosqlbench.engine.api.activityimpl.BaseOpDispenser; -import io.nosqlbench.engine.api.activityimpl.uniform.DriverAdapter; -import io.nosqlbench.engine.api.templating.ParsedOp; -import io.nosqlbench.nb.annotations.ServiceSelector; import io.nosqlbench.api.config.standard.NBConfigModel; import io.nosqlbench.api.config.standard.NBConfiguration; import io.nosqlbench.api.config.standard.NBReconfigurable; +import io.nosqlbench.engine.api.activityapi.ratelimits.RateLimiter; +import io.nosqlbench.engine.api.activityimpl.BaseOpDispenser; +import io.nosqlbench.engine.api.templating.ParsedOp; +import io.nosqlbench.nb.annotations.ServiceSelector; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -39,12 +38,12 @@ public class DiagOpDispenser extends BaseOpDispenser implement private LongFunction spaceF; private OpFunc opFuncs; - public DiagOpDispenser(DriverAdapter adapter, ParsedOp op) { + public DiagOpDispenser(DiagDriverAdapter adapter, LongFunction spaceF, ParsedOp op) { super(adapter,op); - this.opFunc = resolveOpFunc(op); + this.opFunc = resolveOpFunc(spaceF, op); } - private OpFunc resolveOpFunc(ParsedOp op) { + private OpFunc resolveOpFunc(LongFunction spaceF, ParsedOp op) { List tasks = new ArrayList<>(); Set tasknames = op.getDefinedNames(); @@ -82,7 +81,7 @@ public class DiagOpDispenser extends BaseOpDispenser implement // Store the task into the diag op's list of things to do when it runs tasks.add(task); } - this.opFunc = new OpFunc(tasks); + this.opFunc = new OpFunc(spaceF,tasks); return opFunc; } @@ -98,13 +97,17 @@ public class DiagOpDispenser extends BaseOpDispenser implement private final static class OpFunc implements LongFunction, NBReconfigurable { private final List tasks; - public OpFunc(List tasks) { + private final LongFunction spaceF; + + public OpFunc(LongFunction spaceF, List tasks) { this.tasks = tasks; + this.spaceF = spaceF; } @Override public DiagOp apply(long value) { - return new DiagOp(tasks); + DiagSpace space = spaceF.apply(value); + return new DiagOp(space, tasks); } @Override diff --git a/adapter-diag/src/main/java/io/nosqlbench/adapter/diag/DiagOpMapper.java b/adapter-diag/src/main/java/io/nosqlbench/adapter/diag/DiagOpMapper.java index 784bbd1d2..2e7328b1f 100644 --- a/adapter-diag/src/main/java/io/nosqlbench/adapter/diag/DiagOpMapper.java +++ b/adapter-diag/src/main/java/io/nosqlbench/adapter/diag/DiagOpMapper.java @@ -16,14 +16,12 @@ package io.nosqlbench.adapter.diag; -import io.nosqlbench.engine.api.activityimpl.OpDispenser; -import io.nosqlbench.engine.api.activityimpl.OpMapper; -import io.nosqlbench.engine.api.activityimpl.uniform.DriverAdapter; -import io.nosqlbench.engine.api.activityimpl.uniform.DriverSpaceCache; -import io.nosqlbench.engine.api.templating.ParsedOp; import io.nosqlbench.api.config.standard.NBConfigModel; import io.nosqlbench.api.config.standard.NBConfiguration; import io.nosqlbench.api.config.standard.NBReconfigurable; +import io.nosqlbench.engine.api.activityimpl.OpDispenser; +import io.nosqlbench.engine.api.activityimpl.OpMapper; +import io.nosqlbench.engine.api.templating.ParsedOp; import java.util.ArrayList; import java.util.LinkedHashMap; @@ -31,20 +29,17 @@ import java.util.Map; import java.util.function.LongFunction; public class DiagOpMapper implements OpMapper, NBReconfigurable { - private final DriverSpaceCache spaceCache; private final Map dispensers = new LinkedHashMap<>(); - private final DriverAdapter adapter; + private final DiagDriverAdapter adapter; - public DiagOpMapper(DriverAdapter adapter, DriverSpaceCache spaceCache) { - this.spaceCache = spaceCache; + public DiagOpMapper(DiagDriverAdapter adapter) { this.adapter = adapter; } @Override public OpDispenser apply(ParsedOp op) { - DiagOpDispenser dispenser = new DiagOpDispenser(adapter,op); - LongFunction spaceName = op.getAsFunctionOr("space", "default"); - LongFunction spacef = l -> spaceCache.get(spaceName.apply(l)); + LongFunction spaceF = adapter.getSpaceFunc(op); + DiagOpDispenser dispenser = new DiagOpDispenser(adapter,spaceF,op); dispensers.put(op.getName(),dispenser); return dispenser; } diff --git a/adapter-diag/src/main/java/io/nosqlbench/adapter/diag/DiagSpace.java b/adapter-diag/src/main/java/io/nosqlbench/adapter/diag/DiagSpace.java index 8c5dd3fe9..4a8ca3d2c 100644 --- a/adapter-diag/src/main/java/io/nosqlbench/adapter/diag/DiagSpace.java +++ b/adapter-diag/src/main/java/io/nosqlbench/adapter/diag/DiagSpace.java @@ -26,13 +26,14 @@ import io.nosqlbench.api.config.standard.Param; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -public class DiagSpace implements ActivityDefObserver { +public class DiagSpace implements ActivityDefObserver, AutoCloseable { private final Logger logger = LogManager.getLogger(DiagSpace.class); private final NBConfiguration cfg; private final String name; private RateLimiter diagRateLimiter; private long interval; + private boolean errorOnClose; public DiagSpace(String name, NBConfiguration cfg) { this.cfg = cfg; @@ -42,11 +43,13 @@ public class DiagSpace implements ActivityDefObserver { public void applyConfig(NBConfiguration cfg) { this.interval = cfg.get("interval",long.class); + this.errorOnClose = cfg.get("erroronclose",boolean.class); } public static NBConfigModel getConfigModel() { return ConfigModel.of(DiagSpace.class) .add(Param.defaultTo("interval",1000)) + .add(Param.defaultTo("erroronclose", false)) .asReadOnly(); } @@ -61,4 +64,12 @@ public class DiagSpace implements ActivityDefObserver { NBConfiguration cfg = getConfigModel().apply(activityDef.getParams().getStringStringMap()); this.applyConfig(cfg); } + + @Override + public void close() throws Exception { + logger.debug("closing diag space '" + this.name + "'"); + if (errorOnClose) { + throw new RuntimeException("diag space was configured to throw this error when it was configured."); + } + } } diff --git a/adapters-api/src/main/java/io/nosqlbench/engine/api/activityimpl/uniform/BaseDriverAdapter.java b/adapters-api/src/main/java/io/nosqlbench/engine/api/activityimpl/uniform/BaseDriverAdapter.java index 1eba69f2a..3e4ffef9d 100644 --- a/adapters-api/src/main/java/io/nosqlbench/engine/api/activityimpl/uniform/BaseDriverAdapter.java +++ b/adapters-api/src/main/java/io/nosqlbench/engine/api/activityimpl/uniform/BaseDriverAdapter.java @@ -20,6 +20,8 @@ import io.nosqlbench.api.config.standard.*; import io.nosqlbench.engine.api.activityimpl.uniform.fieldmappers.FieldDestructuringMapper; import io.nosqlbench.engine.api.activityimpl.uniform.flowtypes.Op; import io.nosqlbench.engine.api.templating.ParsedOp; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.util.ArrayList; import java.util.List; @@ -29,7 +31,8 @@ import java.util.function.Function; import java.util.function.LongFunction; import java.util.stream.Collectors; -public abstract class BaseDriverAdapter implements DriverAdapter, NBConfigurable, NBReconfigurable { +public abstract class BaseDriverAdapter implements DriverAdapter, NBConfigurable, NBReconfigurable { + private final static Logger logger = LogManager.getLogger("ADAPTER"); private DriverSpaceCache spaceCache; private NBConfiguration cfg; @@ -43,22 +46,22 @@ public abstract class BaseDriverAdapter implements DriverAdapter */ @Override public final Function, Map> getPreprocessor() { - List,Map>> mappers = new ArrayList<>(); - List,Map>> stmtRemappers = + List, Map>> mappers = new ArrayList<>(); + List, Map>> stmtRemappers = getOpStmtRemappers().stream() - .map(m -> new FieldDestructuringMapper("stmt",m)) + .map(m -> new FieldDestructuringMapper("stmt", m)) .collect(Collectors.toList()); mappers.addAll(stmtRemappers); mappers.addAll(getOpFieldRemappers()); - if (mappers.size()==0) { + if (mappers.size() == 0) { return (i) -> i; } - Function,Map> remapper = null; + Function, Map> remapper = null; for (int i = 0; i < mappers.size(); i++) { - if (i==0) { - remapper=mappers.get(i); + if (i == 0) { + remapper = mappers.get(i); } else { remapper = remapper.andThen(mappers.get(i)); } @@ -102,7 +105,7 @@ public abstract class BaseDriverAdapter implements DriverAdapter * * @return A list of optionally applied remapping functions. */ - public List>>> getOpStmtRemappers() { + public List>>> getOpStmtRemappers() { return List.of(); } @@ -112,14 +115,14 @@ public abstract class BaseDriverAdapter implements DriverAdapter * @return */ @Override - public List,Map>> getOpFieldRemappers() { + public List, Map>> getOpFieldRemappers() { return List.of(); } @Override public synchronized final DriverSpaceCache getSpaceCache() { - if (spaceCache==null) { - spaceCache=new DriverSpaceCache<>(getSpaceInitializer(getConfiguration())); + if (spaceCache == null) { + spaceCache = new DriverSpaceCache<>(getSpaceInitializer(getConfiguration())); } return spaceCache; } @@ -149,7 +152,7 @@ public abstract class BaseDriverAdapter implements DriverAdapter public NBConfigModel getConfigModel() { return ConfigModel.of(BaseDriverAdapter.class) .add(Param.optional("alias")) - .add(Param.defaultTo("strict",true,"strict op field mode, which requires that provided op fields are recognized and used")) + .add(Param.defaultTo("strict", true, "strict op field mode, which requires that provided op fields are recognized and used")) .add(Param.optional(List.of("op", "stmt", "statement"), String.class, "op template in statement form")) .add(Param.optional("tags", String.class, "tags to be used to filter operations")) .add(Param.defaultTo("errors", "stop", "error handler configuration")) @@ -162,7 +165,7 @@ public abstract class BaseDriverAdapter implements DriverAdapter .add(Param.optional("seq", String.class, "sequencing algorithm")) .add(Param.optional("instrument", Boolean.class)) .add(Param.optional(List.of("workload", "yaml"), String.class, "location of workload yaml file")) - .add(Param.optional("driver",String.class)) + .add(Param.optional("driver", String.class)) .asReadOnly(); } diff --git a/adapters-api/src/main/java/io/nosqlbench/engine/api/activityimpl/uniform/DriverAdapter.java b/adapters-api/src/main/java/io/nosqlbench/engine/api/activityimpl/uniform/DriverAdapter.java index 6f42f8cf4..14bfae422 100644 --- a/adapters-api/src/main/java/io/nosqlbench/engine/api/activityimpl/uniform/DriverAdapter.java +++ b/adapters-api/src/main/java/io/nosqlbench/engine/api/activityimpl/uniform/DriverAdapter.java @@ -148,7 +148,15 @@ public interface DriverAdapter { DriverSpaceCache getSpaceCache(); /** - * @return A function which can initialize a new S + * This method allows each driver adapter to create named state which is automatically + * cached and re-used by name. For each (driver,space) combination in an activity, + * a distinct space instance will be created. In general, adapter developers will + * use the space type associated with an adapter to wrap native driver instances + * one-to-one. As such, if the space implementation is a {@link AutoCloseable}, + * it will be explicitly shutdown as part of the activity shutdown. + * + * @return A function which can initialize a new Space, which is a place to hold + * object state related to retained objects for the lifetime of a native driver. */ default Function getSpaceInitializer(NBConfiguration cfg) { return n -> null; diff --git a/adapters-api/src/main/java/io/nosqlbench/engine/api/activityimpl/uniform/DriverSpaceCache.java b/adapters-api/src/main/java/io/nosqlbench/engine/api/activityimpl/uniform/DriverSpaceCache.java index 2ecf5bd48..f8bc6e4f4 100644 --- a/adapters-api/src/main/java/io/nosqlbench/engine/api/activityimpl/uniform/DriverSpaceCache.java +++ b/adapters-api/src/main/java/io/nosqlbench/engine/api/activityimpl/uniform/DriverSpaceCache.java @@ -16,6 +16,8 @@ package io.nosqlbench.engine.api.activityimpl.uniform; +import java.util.Collections; +import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; @@ -64,4 +66,8 @@ public class DriverSpaceCache { return cache.computeIfAbsent(name, newSpaceFunction); } + public Map getElements() { + return Collections.unmodifiableMap(cache); + } + } diff --git a/engine-api/src/main/java/io/nosqlbench/engine/api/activityimpl/uniform/StandardAction.java b/engine-api/src/main/java/io/nosqlbench/engine/api/activityimpl/uniform/StandardAction.java index a9b61b51c..0e1612afd 100644 --- a/engine-api/src/main/java/io/nosqlbench/engine/api/activityimpl/uniform/StandardAction.java +++ b/engine-api/src/main/java/io/nosqlbench/engine/api/activityimpl/uniform/StandardAction.java @@ -53,11 +53,13 @@ public class StandardAction, R extends Op> impl private final Timer bindTimer; private final NBErrorHandler errorHandler; private final OpSequence> opsequence; + private final int maxTries; public StandardAction(A activity, int slot) { this.activity = activity; this.opsequence = activity.getOpSequence(); this.slot = slot; + this.maxTries = activity.getMaxTries(); bindTimer = activity.getInstrumentation().getOrCreateBindTimer(); executeTimer = activity.getInstrumentation().getOrCreateExecuteTimer(); triesHistogram = activity.getInstrumentation().getOrCreateTriesHistogram(); @@ -84,7 +86,7 @@ public class StandardAction, R extends Op> impl while (op != null) { int tries = 0; - while (tries++ <= activity.getMaxTries()) { + while (tries++ <= maxTries) { Throwable error = null; long startedAt = System.nanoTime(); diff --git a/engine-api/src/main/java/io/nosqlbench/engine/api/activityimpl/uniform/StandardActivity.java b/engine-api/src/main/java/io/nosqlbench/engine/api/activityimpl/uniform/StandardActivity.java index 13f873991..0b47d30c2 100644 --- a/engine-api/src/main/java/io/nosqlbench/engine/api/activityimpl/uniform/StandardActivity.java +++ b/engine-api/src/main/java/io/nosqlbench/engine/api/activityimpl/uniform/StandardActivity.java @@ -58,12 +58,11 @@ public class StandardActivity extends SimpleActivity implements Optional yaml_loc = activityDef.getParams().getOptionalString("yaml", "workload"); if (yaml_loc.isPresent()) { - Map disposable = new LinkedHashMap<>(activityDef.getParams()); + Map disposable = new LinkedHashMap<>(activityDef.getParams()); StmtsDocList workload = StatementsLoader.loadPath(logger, yaml_loc.get(), disposable, "activities"); yamlmodel = workload.getConfigModel(); - } - else { - yamlmodel= ConfigModel.of(StandardActivity.class).asReadOnly(); + } else { + yamlmodel = ConfigModel.of(StandardActivity.class).asReadOnly(); } ServiceLoader adapterLoader = ServiceLoader.load(DriverAdapter.class); @@ -77,7 +76,7 @@ public class StandardActivity extends SimpleActivity implements List adapterlist = new ArrayList<>(); for (OpTemplate ot : opTemplates) { ParsedOp incompleteOpDef = new ParsedOp(ot, NBConfiguration.empty(), List.of()); - String driverName = incompleteOpDef.takeOptionalStaticValue("driver",String.class) + String driverName = incompleteOpDef.takeOptionalStaticValue("driver", String.class) .or(() -> activityDef.getParams().getOptionalString("driver")) .orElseThrow(() -> new OpConfigError("Unable to identify driver name for op template:\n" + ot)); @@ -99,13 +98,13 @@ public class StandardActivity extends SimpleActivity implements combinedConfig = combinedModel.matchConfig(activityDef.getParams()); configurable.applyConfig(combinedConfig); } - adapters.put(driverName,adapter); - mappers.put(driverName,adapter.getOpMapper()); + adapters.put(driverName, adapter); + mappers.put(driverName, adapter.getOpMapper()); } DriverAdapter adapter = adapters.get(driverName); adapterlist.add(adapter); - ParsedOp pop = new ParsedOp(ot,adapter.getConfiguration(),List.of(adapter.getPreprocessor())); + ParsedOp pop = new ParsedOp(ot, adapter.getConfiguration(), List.of(adapter.getPreprocessor())); Optional discard = pop.takeOptionalStaticValue("driver", String.class); pops.add(pop); } @@ -152,13 +151,13 @@ public class StandardActivity extends SimpleActivity implements if (adapter instanceof NBReconfigurable configurable) { NBConfigModel cfgModel = configurable.getReconfigModel(); NBConfiguration cfg = cfgModel.matchConfig(activityDef.getParams()); - NBReconfigurable.applyMatching(cfg,List.of(configurable)); + NBReconfigurable.applyMatching(cfg, List.of(configurable)); } } } @Override - public List getSyntheticOpTemplates(StmtsDocList stmtsDocList, Map cfg) { + public List getSyntheticOpTemplates(StmtsDocList stmtsDocList, Map cfg) { List opTemplates = new ArrayList<>(); for (DriverAdapter adapter : adapters.values()) { if (adapter instanceof SyntheticOpTemplateProvider sotp) { @@ -169,4 +168,26 @@ public class StandardActivity extends SimpleActivity implements return opTemplates; } + /** + * This is done here since driver adapters are intended to keep all of their state within + * dedicated state space types. Any space which implements {@link io.nosqlbench.engine.api.activityapi.core.Shutdownable} + * will be closed when this activity shuts down. + */ + @Override + public void shutdownActivity() { + for (Map.Entry entry : adapters.entrySet()) { + String adapterName = entry.getKey(); + DriverAdapter adapter = entry.getValue(); + adapter.getSpaceCache().getElements().forEach((spaceName, space) -> { + if (space instanceof AutoCloseable autocloseable) { + try { + autocloseable.close(); + } catch (Exception e) { + throw new RuntimeException("Error while shutting down state space for " + + "adapter=" + adapterName + ", space=" + spaceName + ": " + e, e); + } + } + }); + } + } } diff --git a/engine-api/src/main/java/io/nosqlbench/engine/api/activityapi/core/Shutdownable.java b/nb-api/src/main/java/io/nosqlbench/engine/api/activityapi/core/Shutdownable.java similarity index 100% rename from engine-api/src/main/java/io/nosqlbench/engine/api/activityapi/core/Shutdownable.java rename to nb-api/src/main/java/io/nosqlbench/engine/api/activityapi/core/Shutdownable.java diff --git a/nbr/src/test/java/io/nosqlbench/cli/testing/ExitStatusIntegrationTests.java b/nbr/src/test/java/io/nosqlbench/cli/testing/ExitStatusIntegrationTests.java index 5437c69d3..70a163eaf 100644 --- a/nbr/src/test/java/io/nosqlbench/cli/testing/ExitStatusIntegrationTests.java +++ b/nbr/src/test/java/io/nosqlbench/cli/testing/ExitStatusIntegrationTests.java @@ -86,5 +86,18 @@ class ExitStatusIntegrationTests { assertThat(result.exitStatus).isEqualTo(2); } - +// This will not work reliablyl until the activity shutdown bug is fixed. +// @Test +// public void testCloseErrorHandlerOnSpace() { +// ProcessInvoker invoker = new ProcessInvoker(); +// invoker.setLogDir("logs/test"); +// ProcessResult result = invoker.run("exitstatus_erroronclose", 30, +// java, "-jar", JARNAME, "--logs-dir", "logs/test/error_on_close", "run", +// "driver=diag", "threads=2", "rate=5", "op=noop", "cycles=10", "erroronclose=true", "-vvv" +// ); +// String stdout = String.join("\n", result.getStdoutData()); +// String stderr = String.join("\n", result.getStderrData()); +// assertThat(result.exception).isNotNull(); +// assertThat(result.exception.getMessage()).contains("diag space was configured to throw"); +// } }