more fixes

This commit is contained in:
Jonathan Shook 2023-09-29 18:55:13 -05:00
parent 0a3b827372
commit 90519b9337
13 changed files with 276 additions and 153 deletions

View File

@ -16,31 +16,30 @@
package io.nosqlbench.engine.cli;
import com.codahale.metrics.Gauge;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import io.nosqlbench.adapters.api.activityconfig.rawyaml.RawOpsLoader;
import io.nosqlbench.api.annotations.Annotation;
import io.nosqlbench.api.annotations.Layer;
import io.nosqlbench.api.labels.NBLabeledElement;
import io.nosqlbench.api.labels.NBLabels;
import io.nosqlbench.api.apps.BundledApp;
import io.nosqlbench.api.content.Content;
import io.nosqlbench.api.content.NBIO;
import io.nosqlbench.api.engine.metrics.ActivityMetrics;
import io.nosqlbench.api.engine.metrics.instruments.NBFunctionGauge;
import io.nosqlbench.api.errors.BasicError;
import io.nosqlbench.api.labels.NBLabeledElement;
import io.nosqlbench.api.labels.NBLabels;
import io.nosqlbench.api.logging.NBLogLevel;
import io.nosqlbench.api.metadata.SessionNamer;
import io.nosqlbench.api.metadata.SystemId;
import io.nosqlbench.api.apps.BundledApp;
import io.nosqlbench.engine.api.activityapi.cyclelog.outputs.cyclelog.CycleLogDumperUtility;
import io.nosqlbench.engine.api.activityapi.cyclelog.outputs.cyclelog.CycleLogImporterUtility;
import io.nosqlbench.engine.api.activityapi.input.InputType;
import io.nosqlbench.engine.api.activityapi.output.OutputType;
import io.nosqlbench.adapters.api.activityconfig.rawyaml.RawOpsLoader;
import io.nosqlbench.engine.cli.NBCLIOptions.LoggerConfigData;
import io.nosqlbench.engine.cli.NBCLIOptions.Mode;
import io.nosqlbench.engine.core.annotation.Annotators;
import io.nosqlbench.engine.core.lifecycle.ExecutionResult;
import io.nosqlbench.engine.core.clientload.ClientSystemMetricChecker;
import io.nosqlbench.engine.core.clientload.DiskStatsReader;
import io.nosqlbench.engine.core.clientload.LoadAvgReader;
@ -49,16 +48,12 @@ import io.nosqlbench.engine.core.clientload.NetDevReader;
import io.nosqlbench.engine.core.clientload.StatReader;
import io.nosqlbench.engine.core.lifecycle.process.NBCLIErrorHandler;
import io.nosqlbench.engine.core.lifecycle.activity.ActivityTypeLoader;
import io.nosqlbench.engine.core.lifecycle.process.ShutdownManager;
import io.nosqlbench.engine.core.lifecycle.scenario.ScenariosResults;
import io.nosqlbench.engine.core.lifecycle.process.NBCLIErrorHandler;
import io.nosqlbench.engine.core.lifecycle.scenario.script.MetricsMapper;
import io.nosqlbench.engine.core.lifecycle.session.NBSession;
import io.nosqlbench.engine.core.logging.LoggerConfig;
import io.nosqlbench.engine.core.metadata.MarkdownFinder;
import io.nosqlbench.engine.core.metrics.MetricReporters;
import io.nosqlbench.engine.core.lifecycle.scenario.script.MetricsMapper;
import io.nosqlbench.engine.core.lifecycle.scenario.Scenario;
import io.nosqlbench.engine.core.lifecycle.scenario.ScenariosExecutor;
import io.nosqlbench.engine.core.lifecycle.scenario.script.ScriptParams;
import io.nosqlbench.nb.annotations.Maturity;
import io.nosqlbench.nb.annotations.Service;
import io.nosqlbench.nb.annotations.ServiceSelector;
import org.apache.logging.log4j.LogManager;
@ -175,17 +170,17 @@ public class NBCLI implements Function<String[], Integer>, NBLabeledElement {
.and(globalOptions.getLabelMap());
NBCLI.loggerConfig
.setSessionName(sessionName)
.setConsoleLevel(globalOptions.getConsoleLogLevel())
.setConsolePattern(globalOptions.getConsoleLoggingPattern())
.setLogfileLevel(globalOptions.getScenarioLogLevel())
.setLogfilePattern(globalOptions.getLogfileLoggingPattern())
.setLoggerLevelOverrides(globalOptions.getLogLevelOverrides())
.setMaxLogs(globalOptions.getLogsMax())
.setLogsDirectory(globalOptions.getLogsDirectory())
.setAnsiEnabled(globalOptions.isEnableAnsi())
.setDedicatedVerificationLogger(globalOptions.isDedicatedVerificationLogger())
.activate();
.setSessionName(sessionName)
.setConsoleLevel(globalOptions.getConsoleLogLevel())
.setConsolePattern(globalOptions.getConsoleLoggingPattern())
.setLogfileLevel(globalOptions.getScenarioLogLevel())
.setLogfilePattern(globalOptions.getLogfileLoggingPattern())
.setLoggerLevelOverrides(globalOptions.getLogLevelOverrides())
.setMaxLogs(globalOptions.getLogsMax())
.setLogsDirectory(globalOptions.getLogsDirectory())
.setAnsiEnabled(globalOptions.isEnableAnsi())
.setDedicatedVerificationLogger(globalOptions.isDedicatedVerificationLogger())
.activate();
ConfigurationFactory.setConfigurationFactory(NBCLI.loggerConfig);
NBCLI.logger = LogManager.getLogger("NBCLI");
@ -282,7 +277,7 @@ public class NBCLI implements Function<String[], Integer>, NBLabeledElement {
}
if (options.getWantsListCommands()) {
NBCLICommandParser.RESERVED_WORDS.forEach(System.out::println);
SessionCommandParser.RESERVED_WORDS.forEach(System.out::println);
return NBCLI.EXIT_OK;
}
if (options.wantsActivityTypes()) {
@ -310,19 +305,19 @@ public class NBCLI implements Function<String[], Integer>, NBLabeledElement {
NBCLI.logger.debug(() -> "user requests to copy out " + resourceToCopy);
Optional<Content<?>> tocopy = NBIO.classpath()
.searchPrefixes("activities")
.searchPrefixes(options.wantsIncludes())
.pathname(resourceToCopy).extensionSet(RawOpsLoader.YAML_EXTENSIONS).first();
.searchPrefixes("activities")
.searchPrefixes(options.wantsIncludes())
.pathname(resourceToCopy).extensionSet(RawOpsLoader.YAML_EXTENSIONS).first();
if (tocopy.isEmpty()) tocopy = NBIO.classpath()
.searchPrefixes().searchPrefixes(options.wantsIncludes())
.searchPrefixes(options.wantsIncludes())
.pathname(resourceToCopy).first();
.searchPrefixes().searchPrefixes(options.wantsIncludes())
.searchPrefixes(options.wantsIncludes())
.pathname(resourceToCopy).first();
final Content<?> data = tocopy.orElseThrow(
() -> new BasicError(
"Unable to find " + resourceToCopy +
" in classpath to copy out")
() -> new BasicError(
"Unable to find " + resourceToCopy +
" in classpath to copy out")
);
final Path writeTo = Path.of(data.asPath().getFileName().toString());
@ -360,7 +355,7 @@ public class NBCLI implements Function<String[], Integer>, NBLabeledElement {
if (options.wantsTopicalHelp()) {
final Optional<String> helpDoc = MarkdownFinder.forHelpTopic(options.wantsTopicalHelpFor());
System.out.println(helpDoc.orElseThrow(
() -> new RuntimeException("No help could be found for " + options.wantsTopicalHelpFor())
() -> new RuntimeException("No help could be found for " + options.wantsTopicalHelpFor())
));
return NBCLI.EXIT_OK;
}
@ -376,23 +371,26 @@ public class NBCLI implements Function<String[], Integer>, NBLabeledElement {
NBCLI.logger.debug("initializing annotators with config:'{}'", annotatorsConfig);
Annotators.init(annotatorsConfig, options.getAnnotateLabelSpec());
Annotators.recordAnnotation(
Annotation.newBuilder()
.element(this)
.now()
.layer(Layer.Session)
.addDetail("cli", String.join("\n", args))
.build()
Annotation.newBuilder()
.element(this)
.now()
.layer(Layer.Session)
.addDetail("cli", String.join("\n", args))
.build()
);
if ((null != reportPromPushTo) || (null != reportGraphiteTo) || (null != options.wantsReportCsvTo())) {
final MetricReporters reporters = MetricReporters.getInstance();
reporters.addRegistry("workloads", ActivityMetrics.getMetricRegistry());
if (null != reportPromPushTo) reporters.addPromPush(reportPromPushTo, options.wantsMetricsPrefix(), promPushConfig);
if (null != reportPromPushTo)
reporters.addPromPush(reportPromPushTo, options.wantsMetricsPrefix(), promPushConfig);
if (null != reportGraphiteTo) reporters.addGraphite(reportGraphiteTo, options.wantsMetricsPrefix());
if (null != options.wantsReportCsvTo())
reporters.addCSVReporter(options.wantsReportCsvTo(), options.wantsMetricsPrefix());
if (options.wantsLoggedMetrics()) { reporters.addLogger(); }
if (options.wantsLoggedMetrics()) {
reporters.addLogger();
}
reporters.start(10, options.getReportInterval());
}
@ -408,13 +406,13 @@ public class NBCLI implements Function<String[], Integer>, NBLabeledElement {
}
for (
final LoggerConfigData histoLogger : options.getHistoLoggerConfigs())
final LoggerConfigData histoLogger : options.getHistoLoggerConfigs())
ActivityMetrics.addHistoLogger(sessionName, histoLogger.pattern, histoLogger.file, histoLogger.interval);
for (
final LoggerConfigData statsLogger : options.getStatsLoggerConfigs())
final LoggerConfigData statsLogger : options.getStatsLoggerConfigs())
ActivityMetrics.addStatsLogger(sessionName, statsLogger.pattern, statsLogger.file, statsLogger.interval);
for (
final LoggerConfigData classicConfigs : options.getClassicHistoConfigs())
final LoggerConfigData classicConfigs : options.getClassicHistoConfigs())
ActivityMetrics.addClassicHistos(sessionName, classicConfigs.pattern, classicConfigs.file, classicConfigs.interval);
// client machine metrics; TODO: modify pollInterval
@ -435,70 +433,29 @@ public class NBCLI implements Function<String[], Integer>, NBLabeledElement {
NBCLI.logger.debug(() -> "enabling stack traces since log level is " + options.getConsoleLogLevel());
}
final Scenario scenario = new Scenario(
sessionName,
options.getScriptFile(),
options.getScriptingEngine(),
options.getProgressSpec(),
options.wantsStackTraces(),
options.wantsCompileScript(),
options.getReportSummaryTo(),
String.join("\n", args),
options.getLogsDirectory(),
Maturity.Unspecified,
this);
// intentionally not shown for warn-only
NBCLI.logger.info(() -> "console logging level is " + options.getConsoleLogLevel());
final ScriptBuffer buffer = new BasicScriptBuffer()
.add(options.getCommands()
.toArray(new Cmd[0]));
final String scriptData = buffer.getParsedScript();
if (options.wantsShowScript()) {
System.out.println("// Rendered Script");
System.out.println(scriptData);
return NBCLI.EXIT_OK;
}
if (options.wantsEnableChart()) {
NBCLI.logger.info("Charting enabled");
scenario.enableCharting();
} else NBCLI.logger.info("Charting disabled");
// Execute Scenario!
if (0 == options.getCommands().size()) {
NBCLI.logger.info("No commands provided. Exiting before scenario.");
return NBCLI.EXIT_OK;
}
scenario.addScriptText(scriptData);
final ScriptParams scriptParams = new ScriptParams();
scriptParams.putAll(buffer.getCombinedParams());
scenario.addScenarioScriptParams(scriptParams);
scenariosExecutor.execute(scenario);
final ScenariosResults scenariosResults = scenariosExecutor.awaitAllResults();
NBCLI.logger.debug(() -> "Total of " + scenariosResults.getSize() + " result object returned from ScenariosExecutor");
clientMetricChecker.shutdown();
ActivityMetrics.closeMetrics(options.wantsEnableChart());
scenariosResults.reportToLog();
ShutdownManager.shutdown();
NBCLI.logger.info(scenariosResults.getExecutionSummary());
if (scenariosResults.hasError()) {
final Exception exception = scenariosResults.getOne().getException();
NBCLI.logger.warn(scenariosResults.getExecutionSummary());
NBCLIErrorHandler.handle(exception, options.wantsStackTraces());
System.err.println(exception.getMessage()); // TODO: make this consistent with ConsoleLogging sequencing
return NBCLI.EXIT_ERROR;
}
NBCLI.logger.info(scenariosResults.getExecutionSummary());
return NBCLI.EXIT_OK;
/**
* At this point, the command stream from the CLI should be handed into the session, and the session should
* marshal and transform it for any scenario invocations directly.
*/
NBSession session = new NBSession(
this,
sessionName,
options.getProgressSpec(),
options.getReportSummaryTo(),
options.getLogsDirectory(),
options.getScriptFile(),
options.wantsShowScript()
);
ExecutionResult sessionResult = session.apply(options.getCommands());
sessionResult.printSummary(System.out);
return sessionResult.getStatus().code;
}
private String loadHelpFile(final String filename) {
final ClassLoader cl = this.getClass().getClassLoader();
final InputStream resourceAsStream = cl.getResourceAsStream(filename);

View File

@ -16,15 +16,14 @@
package io.nosqlbench.engine.cli;
import io.nosqlbench.api.labels.NBLabelSpec;
import io.nosqlbench.api.labels.NBLabels;
import io.nosqlbench.api.engine.util.Unit;
import io.nosqlbench.api.errors.BasicError;
import io.nosqlbench.api.labels.NBLabelSpec;
import io.nosqlbench.api.labels.NBLabels;
import io.nosqlbench.api.logging.NBLogLevel;
import io.nosqlbench.api.system.NBStatePath;
import io.nosqlbench.engine.api.metrics.IndicatorMode;
import io.nosqlbench.engine.cli.Cmd.CmdType;
import io.nosqlbench.engine.core.lifecycle.scenario.Scenario.Engine;
import io.nosqlbench.nb.annotations.Maturity;
import java.io.File;
@ -323,7 +322,7 @@ public class NBCLIOptions {
// Now that statdirs is settled, auto load argsfile if it is present
final NBCLIArgsFile argsfile = new NBCLIArgsFile();
argsfile.reserved(NBCLICommandParser.RESERVED_WORDS);
argsfile.reserved(SessionCommandParser.RESERVED_WORDS);
argsfile.preload("--argsfile-optional", NBCLIOptions.ARGS_FILE_DEFAULT);
arglist = argsfile.process(arglist);
@ -645,7 +644,7 @@ public class NBCLIOptions {
}
}
arglist = nonincludes;
final Optional<List<Cmd>> commands = NBCLICommandParser.parse(arglist);
final Optional<List<Cmd>> commands = SessionCommandParser.parse(arglist);
if (commands.isPresent()) cmdList.addAll(commands.get());
else {
final String arg = arglist.peekFirst();

View File

@ -131,9 +131,9 @@ public class BasicScriptBuffer implements ScriptBuffer {
return scriptParams;
}
public static String assemble(NBCLIOptions options) {
public static String assemble(List<Cmd> cmds) {
ScriptBuffer script = new BasicScriptBuffer();
for (Cmd command : options.getCommands()) {
for (Cmd command : cmds) {
script.add(command);
}
return script.getParsedScript();

View File

@ -154,9 +154,9 @@ public class Cmd {
logger.debug(() -> "freeform parameter:" + nextarg);
} else if (nextarg.contains("=")) {
throw new InvalidParameterException(
"command '" + cmdName + "' requires a value for " + arg.name + "" +
"command '" + cmdName + "' requires a value for " + arg.name +
", but a named parameter was found instead: " + nextarg);
} else if (NBCLICommandParser.RESERVED_WORDS.contains(nextarg)) {
} else if (SessionCommandParser.RESERVED_WORDS.contains(nextarg)) {
throw new InvalidParameterException(
"command '" + cmdName + "' requires a value for " + arg.name
+ ", but a reserved word was found instead: " + nextarg);
@ -167,7 +167,7 @@ public class Cmd {
}
while (arglist.size() > 0 &&
!NBCLICommandParser.RESERVED_WORDS.contains(arglist.peekFirst())
!SessionCommandParser.RESERVED_WORDS.contains(arglist.peekFirst())
&& arglist.peekFirst().contains("=")) {
String arg = arglist.removeFirst();
String[] assigned = arg.split("=", 2);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022 nosqlbench
* Copyright (c) 2022-2023 nosqlbench
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -27,7 +27,7 @@ import java.util.*;
* If the optional is empty, then it means some part of the command structure
* was not recognized.
*/
public class NBCLICommandParser {
public class SessionCommandParser {
private static final String FRAGMENT = "fragment";
private static final String SCRIPT = "script";

View File

@ -19,6 +19,8 @@ package io.nosqlbench.engine.core.lifecycle;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.PrintStream;
/**
* Provide a result type back to a caller, including the start and end times,
* any exception that occurred, and any content written to stdout or stderr equivalent
@ -27,6 +29,22 @@ import org.apache.logging.log4j.Logger;
*/
public class ExecutionResult {
protected final static Logger logger = LogManager.getLogger(ExecutionResult.class);
protected final Status status;
public void printSummary(PrintStream out) {
out.println(this);
}
public enum Status {
OK(0),
WARNING(1),
ERROR(2);
public final int code;
Status(int code) {
this.code = code;
}
}
protected final long startedAt;
protected final long endedAt;
protected final Exception exception;
@ -37,7 +55,9 @@ public class ExecutionResult {
this.endedAt = endedAt;
this.exception = error;
this.iolog = ((iolog != null) ? iolog + "\n\n" : "") + exception;
logger.debug("populating "+(error==null ? "NORMAL" : "ERROR")+" scenario result");
this.status = (error==null) ? Status.OK : Status.ERROR;
logger.debug("populating "+status+" scenario result");
// if (logger.isTraceEnabled()) {
// StackTraceElement[] st = Thread.currentThread().getStackTrace();
// for (int i = 0; i < st.length; i++) {
@ -63,4 +83,10 @@ public class ExecutionResult {
public Exception getException() {
return exception;
}
public Status getStatus() {
return this.status;
}
}

View File

@ -21,22 +21,18 @@ import io.nosqlbench.api.annotations.Annotation;
import io.nosqlbench.api.annotations.Layer;
import io.nosqlbench.api.labels.NBLabeledElement;
import io.nosqlbench.api.labels.NBLabels;
import io.nosqlbench.api.engine.metrics.ActivityMetrics;
import io.nosqlbench.api.metadata.ScenarioMetadata;
import io.nosqlbench.api.metadata.ScenarioMetadataAware;
import io.nosqlbench.api.metadata.SystemId;
import io.nosqlbench.api.extensions.ScriptingExtensionPluginInfo;
import io.nosqlbench.engine.api.scripting.ScriptEnvBuffer;
import io.nosqlbench.engine.core.annotation.Annotators;
import io.nosqlbench.engine.core.lifecycle.ExecutionMetricsResult;
import io.nosqlbench.engine.core.lifecycle.activity.ActivityProgressIndicator;
import io.nosqlbench.api.extensions.SandboxExtensionFinder;
import io.nosqlbench.engine.core.lifecycle.scenario.script.ScenarioContext;
import io.nosqlbench.engine.core.lifecycle.scenario.script.ScriptParams;
import io.nosqlbench.engine.core.lifecycle.scenario.script.bindings.ActivityBindings;
import io.nosqlbench.engine.core.lifecycle.scenario.script.bindings.PolyglotMetricRegistryBindings;
import io.nosqlbench.engine.core.lifecycle.scenario.script.bindings.PolyglotScenarioController;
import io.nosqlbench.nb.annotations.Maturity;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.graalvm.polyglot.Context;
@ -58,14 +54,13 @@ import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.stream.Collectors;
public class Scenario implements Callable<ExecutionMetricsResult>, NBLabeledElement {
private final String commandLine;
private final String reportSummaryTo;
private final Path logsPath;
private final Maturity minMaturity;
private final Invocation invocation;
private final String scriptfile;
private Logger logger = LogManager.getLogger("SCENARIO");
private State state = State.Scheduled;
@ -80,6 +75,11 @@ public class Scenario implements Callable<ExecutionMetricsResult>, NBLabeledElem
return Optional.ofNullable(result);
}
public enum Invocation {
RENDER_SCRIPT,
EXECUTE_SCRIPT
}
@Override
public NBLabels getLabels() {
return this.parentComponent.getLabels().and("scenario", this.scenarioName);
@ -92,6 +92,7 @@ public class Scenario implements Callable<ExecutionMetricsResult>, NBLabeledElem
Interrupted,
Finished
}
private final List<String> scripts = new ArrayList<>();
private ScriptEngine scriptEngine;
private ScenarioController scenarioController;
@ -100,10 +101,7 @@ public class Scenario implements Callable<ExecutionMetricsResult>, NBLabeledElem
private ScenarioContext scriptEnv;
private final String scenarioName;
private ScriptParams scenarioScriptParams;
private final String scriptfile;
private Engine engine = Engine.Graalvm;
private final boolean wantsStackTraces;
private final boolean wantsCompiledScript;
private final Engine engine = Engine.Graalvm;
private long startedAtMillis = -1L;
private long endedAtMillis = -1L;
@ -113,32 +111,34 @@ public class Scenario implements Callable<ExecutionMetricsResult>, NBLabeledElem
public Scenario(
final String scenarioName,
final String scriptfile,
final Engine engine,
final String progressInterval,
final boolean wantsStackTraces,
final boolean wantsCompiledScript,
final String reportSummaryTo,
final String commandLine,
final Path logsPath,
final Maturity minMaturity,
NBLabeledElement parentComponent) {
String scriptfile,
NBComponent parentComponent,
Invocation invocation
) {
super(parentComponent, NBLabels.forKV("scenario", scenarioName));
this.scenarioName = scenarioName;
this.scriptfile = scriptfile;
this.engine = engine;
this.progressInterval = progressInterval;
this.wantsStackTraces = wantsStackTraces;
this.wantsCompiledScript = wantsCompiledScript;
this.reportSummaryTo = reportSummaryTo;
this.commandLine = commandLine;
this.logsPath = logsPath;
this.minMaturity = minMaturity;
this.scriptfile = scriptfile;
this.parentComponent = parentComponent;
this.invocation = invocation;
}
public static Scenario forTesting(final String name, final Engine engine, final String reportSummaryTo, final Maturity minMaturity) {
return new Scenario(name, null, engine, "console:10s", true, true, reportSummaryTo, "", Path.of("logs"), minMaturity, NBLabeledElement.forKV("test_name", "name"));
public static Scenario forTesting(final String name, final String reportSummaryTo, NBComponent parent) {
return new Scenario(
name,
"console:10s",
reportSummaryTo,
Path.of("logs"),
"",
new NBBaseComponent(parent,NBLabels.forKV("test","testrun")),
Invocation.EXECUTE_SCRIPT
);
}
public Scenario setLogger(final Logger logger) {
@ -351,7 +351,7 @@ public class Scenario implements Callable<ExecutionMetricsResult>, NBLabeledElem
.element(this)
.interval(startedAtMillis, this.endedAtMillis)
.layer(Layer.Scenario)
.addDetail("event","stop-scenario")
.addDetail("event", "stop-scenario")
.build();
Annotators.recordAnnotation(annotation);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022 nosqlbench
* Copyright (c) 2022-2023 nosqlbench
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -17,11 +17,14 @@
package io.nosqlbench.engine.core.lifecycle.scenario;
import io.nosqlbench.engine.core.lifecycle.ExecutionMetricsResult;
import org.apache.logging.log4j.Logger;
import io.nosqlbench.engine.core.lifecycle.ExecutionResult;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
public class ScenariosResults {
@ -75,6 +78,11 @@ public class ScenariosResults {
.anyMatch(r -> r.getException()!=null);
}
public Optional<Exception> getAnyError() {
return this.scenarioResultMap.values().stream()
.map(ExecutionResult::getException).filter(Objects::nonNull).findFirst();
}
public int getSize() {
return this.scenarioResultMap.size();
}

View File

@ -0,0 +1,133 @@
/*
* Copyright (c) 2023 nosqlbench
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.nosqlbench.engine.core.lifecycle.session;
import io.nosqlbench.api.config.NBComponent;
import io.nosqlbench.api.config.standard.NBBaseComponent;
import io.nosqlbench.api.engine.metrics.ActivityMetrics;
import io.nosqlbench.api.labels.NBLabels;
import io.nosqlbench.engine.cli.BasicScriptBuffer;
import io.nosqlbench.engine.cli.Cmd;
import io.nosqlbench.engine.cli.ScriptBuffer;
import io.nosqlbench.engine.core.lifecycle.ExecutionResult;
import io.nosqlbench.engine.core.lifecycle.process.NBCLIErrorHandler;
import io.nosqlbench.engine.core.lifecycle.process.ShutdownManager;
import io.nosqlbench.engine.core.lifecycle.scenario.Scenario;
import io.nosqlbench.engine.core.lifecycle.scenario.ScenariosExecutor;
import io.nosqlbench.engine.core.lifecycle.scenario.ScenariosResults;
import io.nosqlbench.engine.core.lifecycle.scenario.script.ScriptParams;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.nio.file.Path;
import java.util.List;
import java.util.function.Function;
/**
* A session represents a single execution of NoSQLBench, whether episodic or persistent under some service layer.
* An NBSession takes care of system level concerns like logging, annotations, error reporting, metrics flows, and so
* on.
* All NBScenarios are run within an NBSession.
*/
public class NBSession extends NBBaseComponent implements Function<List<Cmd>, ExecutionResult> {
private final static Logger logger = LogManager.getLogger(NBSession.class);
private final String sessionName;
private final String progressSpec;
private final String reportSummaryTo;
private final Path logspath;
private final boolean wantsShowScript;
private final String scriptfile;
public enum STATUS {
OK,
WARNING,
ERROR
}
public NBSession(
NBComponent parent,
String sessionName,
String progressSpec,
String reportSummaryTo,
Path logspath,
String scriptfile,
boolean wantsShowScript
) {
super(parent, NBLabels.forKV("session", sessionName));
this.sessionName = sessionName;
this.progressSpec = progressSpec;
this.reportSummaryTo = reportSummaryTo;
this.logspath = logspath;
this.scriptfile = scriptfile;
this.wantsShowScript = wantsShowScript;
}
public ExecutionResult apply(List<Cmd> cmds) {
ResultCollector collector = new ResultCollector();
try (ResultContext results = new ResultContext(collector)) {
final ScenariosExecutor scenariosExecutor = new ScenariosExecutor("executor-" + sessionName, 1);
Scenario.Invocation invocation = wantsShowScript ? Scenario.Invocation.RENDER_SCRIPT : Scenario.Invocation.EXECUTE_SCRIPT;
final Scenario scenario = new Scenario(
sessionName,
progressSpec,
reportSummaryTo,
logspath,
scriptfile,
this,
invocation
);
final ScriptBuffer buffer = new BasicScriptBuffer().add(cmds.toArray(new Cmd[0]));
final String scriptData = buffer.getParsedScript();
// Execute Scenario!
if (cmds.isEmpty()) {
logger.info("No commands provided.");
}
scenario.addScriptText(scriptData);
final ScriptParams scriptParams = new ScriptParams();
scriptParams.putAll(buffer.getCombinedParams());
scenario.addScenarioScriptParams(scriptParams);
scenariosExecutor.execute(scenario);
final ScenariosResults scenariosResults = scenariosExecutor.awaitAllResults();
logger.debug(() -> "Total of " + scenariosResults.getSize() + " result object returned from ScenariosExecutor");
ActivityMetrics.closeMetrics();
scenariosResults.reportToLog();
ShutdownManager.shutdown();
logger.info(scenariosResults.getExecutionSummary());
if (scenariosResults.hasError()) {
results.error(scenariosResults.getAnyError().orElseThrow());
final Exception exception = scenariosResults.getOne().getException();
logger.warn(scenariosResults.getExecutionSummary());
NBCLIErrorHandler.handle(exception, true);
System.err.println(exception.getMessage()); // TODO: make this consistent with ConsoleLogging sequencing
}
results.output(scenariosResults.getExecutionSummary());
}
return collector.toExecutionResult();
}
}

View File

@ -16,9 +16,9 @@
package io.nosqlbench.engine.core;
import io.nosqlbench.api.config.standard.TestComponent;
import io.nosqlbench.engine.api.scripting.ScriptEnvBuffer;
import io.nosqlbench.engine.core.lifecycle.scenario.Scenario;
import io.nosqlbench.nb.annotations.Maturity;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.jupiter.api.Test;
@ -31,7 +31,7 @@ public class ScenarioTest {
@Test
public void shouldLoadScriptText() {
ScriptEnvBuffer buffer = new ScriptEnvBuffer();
Scenario scenario = Scenario.forTesting("testing", Scenario.Engine.Graalvm, "stdout:300", Maturity.Any);
Scenario scenario = Scenario.forTesting("testing", "stdout:300", new TestComponent());
scenario.addScriptText("print('loaded script environment...');\n");
try {
var result=scenario.call();

View File

@ -16,11 +16,11 @@
package io.nosqlbench.nbr.examples;
import io.nosqlbench.api.config.standard.TestComponent;
import io.nosqlbench.engine.core.lifecycle.ExecutionMetricsResult;
import io.nosqlbench.engine.core.lifecycle.scenario.Scenario;
import io.nosqlbench.engine.core.lifecycle.scenario.ScenariosExecutor;
import io.nosqlbench.engine.core.lifecycle.scenario.ScenariosResults;
import io.nosqlbench.nb.annotations.Maturity;
import org.apache.commons.compress.utils.IOUtils;
import org.assertj.core.data.Offset;
import org.junit.jupiter.api.BeforeAll;
@ -56,7 +56,7 @@ public class ScriptExampleTests {
String scenarioName = "scenario " + scriptname;
System.out.println("=".repeat(29) + " Running integration test for example scenario: " + scenarioName);
ScenariosExecutor executor = new ScenariosExecutor(ScriptExampleTests.class.getSimpleName() + ":" + scriptname, 1);
Scenario s = Scenario.forTesting(scenarioName, Scenario.Engine.Graalvm,"stdout:300", Maturity.Any);
Scenario s = Scenario.forTesting(scenarioName,"stdout:300", new TestComponent());
s.addScenarioScriptParams(paramsMap);