diff --git a/engine-api/src/main/java/io/nosqlbench/engine/api/util/NosqlBenchFiles.java b/engine-api/src/main/java/io/nosqlbench/engine/api/util/NosqlBenchFiles.java index d9bcb9261..4d9702a0b 100644 --- a/engine-api/src/main/java/io/nosqlbench/engine/api/util/NosqlBenchFiles.java +++ b/engine-api/src/main/java/io/nosqlbench/engine/api/util/NosqlBenchFiles.java @@ -17,16 +17,29 @@ package io.nosqlbench.engine.api.util; +import io.nosqlbench.docsys.core.PathWalker; +import io.nosqlbench.engine.api.activityconfig.StatementsLoader; +import io.nosqlbench.engine.api.activityconfig.yaml.Scenarios; +import io.nosqlbench.engine.api.activityconfig.yaml.StmtsDocList; +import io.nosqlbench.virtdata.api.VirtDataResources; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.io.*; +import java.net.URI; +import java.net.URISyntaxException; import java.net.URL; +import java.nio.file.Files; import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Optional; +import java.nio.file.Paths; +import java.util.*; import java.util.stream.Collectors; +import java.util.stream.Stream; public class NosqlBenchFiles { + private final static Logger logger = LoggerFactory.getLogger(NosqlBenchFiles.class); + public static InputStream findRequiredStreamOrFile(String basename, String extension, String... searchPaths) { Optional optionalStreamOrFile = findOptionalStreamOrFile(basename, extension, searchPaths); return optionalStreamOrFile.orElseThrow(() -> new RuntimeException( @@ -131,4 +144,29 @@ public class NosqlBenchFiles { throw new RuntimeException("Error while reading required file to string", ioe); } } + + public static Map> getWorkloadsWithScenarioScripts() { + + String dir = "activities/"; + + Path basePath = VirtDataResources.findPathIn(dir); + List yamlPathList = PathWalker.findAll(basePath).stream().filter(f -> f.toString().endsWith(".yaml")).collect(Collectors.toList()); + + HashMap workloadMap = new HashMap(); + for (Path yamlPath : yamlPathList) { + String substring = yamlPath.toString().substring(1); + StmtsDocList stmts = StatementsLoader.load(logger, substring); + + Scenarios scenarios = stmts.getDocScenarios(); + + List scenarioNames = scenarios.getScenarioNames(); + + if (scenarioNames != null && scenarioNames.size() >0){ + workloadMap.put(yamlPath.getFileName().toString(), scenarioNames); + } + } + + return workloadMap; + } + } diff --git a/engine-cli/src/main/java/io/nosqlbench/engine/cli/NBCLI.java b/engine-cli/src/main/java/io/nosqlbench/engine/cli/NBCLI.java index 0f7ae5e9c..f6218caa7 100644 --- a/engine-cli/src/main/java/io/nosqlbench/engine/cli/NBCLI.java +++ b/engine-cli/src/main/java/io/nosqlbench/engine/cli/NBCLI.java @@ -5,6 +5,7 @@ import io.nosqlbench.engine.api.activityapi.cyclelog.outputs.cyclelog.CycleLogDu 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.engine.api.util.NosqlBenchFiles; import io.nosqlbench.engine.core.MarkdownDocInfo; import io.nosqlbench.engine.core.ScenarioLogger; import io.nosqlbench.engine.core.ScenariosResults; @@ -24,6 +25,8 @@ import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Arrays; +import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; @@ -43,7 +46,7 @@ public class NBCLI { cli.run(args); } - public void run(String[] args) { + public void run(String[] args) { if (args.length>0 && args[0].toLowerCase().equals("virtdata")) { VirtDataMainApp.main(Arrays.copyOfRange(args,1,args.length)); System.exit(0); @@ -80,6 +83,24 @@ public class NBCLI { System.exit(0); } + if (options.wantsWorkloads()) { + //ActivityType.FINDER.getAll().stream().map(ActivityType::getName).forEach(System.out::println); + Map> workloads = NosqlBenchFiles.getWorkloadsWithScenarioScripts(); + for (Map.Entry> entry : workloads.entrySet()) { + System.out.println("# from: "+ entry.getKey()); + List scenarioList = entry.getValue(); + String workloadName = entry.getKey().replaceAll("\\.yaml", "") ; + + for (String scenario : scenarioList) { + if (scenario.equals("default")) { + scenario = scenario + " # same as running ./nb " + workloadName ; + } + System.out.println(" ./nb " + workloadName + " " + scenario); + } + } + System.exit(0); + } + if (options.wantsInputTypes()) { InputType.FINDER.getAll().stream().map(InputType::getName).forEach(System.out::println); System.exit(0); diff --git a/engine-cli/src/main/java/io/nosqlbench/engine/cli/NBCLIOptions.java b/engine-cli/src/main/java/io/nosqlbench/engine/cli/NBCLIOptions.java index 28cc4ba63..190faf6d3 100644 --- a/engine-cli/src/main/java/io/nosqlbench/engine/cli/NBCLIOptions.java +++ b/engine-cli/src/main/java/io/nosqlbench/engine/cli/NBCLIOptions.java @@ -34,6 +34,7 @@ public class NBCLIOptions { private static final String ADVANCED_HELP = "--advanced-help"; private static final String METRICS = "--list-metrics"; private static final String ACTIVITY_TYPES = "--list-activity-types"; + private static final String WORKLOADS = "--list-workloads"; private static final String WANTS_INPUT_TYPES = "--list-input-types"; private static final String WANTS_OUTPUT_TYPES = "--list-output-types"; private static final String WANTS_VERSION_COORDS = "--version-coords"; @@ -115,6 +116,7 @@ public class NBCLIOptions { private Map logLevelsOverrides = new HashMap<>(); private boolean enableChart = false; private boolean dockerMetrics = false; + private boolean wantsWorkloads = false; public NBCLIOptions(String[] args) { parse(args); @@ -311,25 +313,33 @@ public class NBCLIOptions { arglist.removeFirst(); consoleLoggingPattern = readWordOrThrow(arglist, "logging pattern"); break; + case WORKLOADS: + arglist.removeFirst(); + wantsWorkloads = true; + break; default: Optional optionalScript = NosqlBenchFiles.findOptionalStreamOrFile(word, "js", "scripts/auto"); + //Script if (optionalScript.isPresent()) { arglist.removeFirst(); arglist.addFirst("scripts/auto/" + word); arglist.addFirst("script"); Cmd script = parseScriptCmd(arglist); cmdList.add(script); + //Scripted yaml } else { - Optional path = NosqlBenchFiles.findOptionalPath(word, "yaml", "activities", "activities/baselines"); + Optional path = NosqlBenchFiles.findOptionalPath(word, "yaml", "activities"); if(path.isPresent()){ arglist.removeFirst(); String scenarioFilter = null; + //Named scenario if (arglist.size() > 0 && !arglist.peekFirst().contains("=")){ scenarioFilter = arglist.peekFirst(); arglist.removeFirst(); - }; - arglist.addFirst("yaml="+path.get().toString()); + } + + //arglist.addFirst("yaml="+path.get().toString()); parseWorkloadYamlCmds(path.get().toString(), arglist, scenarioFilter); } else { @@ -353,6 +363,23 @@ public class NBCLIOptions { List cmds = scenarios.getNamedScenario(scenarioName); + Map paramMap = new HashMap<>(); + while(arglist.size() > 0 && arglist.peekFirst().contains("=")){ + String arg = arglist.removeFirst(); + for(int i =0 ; i< cmds.size(); i++){ + String yamlCmd = cmds.get(i); + String[] argArray = arg.split("="); + String argKey = argArray[0]; + String argValue = argArray[1]; + if (!yamlCmd.contains(argKey)) { + cmds.set(i, yamlCmd +" " + arg); + }else{ + paramMap.put(argKey, argValue); + } + } + } + + if (cmds == null){ List names = scenarios.getScenarioNames(); throw new RuntimeException("Unknown scenario name, make sure the scenario name you provide exists in the workload definition (yaml):\n" + String.join(",", names)); @@ -361,7 +388,6 @@ public class NBCLIOptions { for (String cmd : cmds) { String[] cmdArray = cmd.split(" "); - Map paramMap = new HashMap<>(); for (String parameter: cmdArray) { if (parameter.contains("=")){ if ( !parameter.contains("TEMPLATE(") && !parameter.contains("<<")) { @@ -378,9 +404,8 @@ public class NBCLIOptions { // Is there a better way to do this than regex? parse(cmd.split(" ")); - } - arglist.removeFirst(); + } } private Map parseLogLevelOverrides(String levelsSpec) { @@ -517,7 +542,7 @@ public class NBCLIOptions { assertNotParameter(scriptName); Map scriptParams = new LinkedHashMap<>(); while (arglist.size() > 0 && !reserved_words.contains(arglist.peekFirst()) - && arglist.peekFirst().contains("=")) { + && arglist.peekFirst().contains("=")) { String[] split = arglist.removeFirst().split("=", 2); scriptParams.put(split[0], split[1]); } @@ -534,8 +559,8 @@ public class NBCLIOptions { String cmdType = arglist.removeFirst(); List activitydef = new ArrayList(); while (arglist.size() > 0 && - !reserved_words.contains(arglist.peekFirst()) - && arglist.peekFirst().contains("=")) { + !reserved_words.contains(arglist.peekFirst()) + && arglist.peekFirst().contains("=")) { activitydef.add(arglist.removeFirst()); } return new Cmd(CmdType.valueOf(cmdType), activitydef.stream().map(s -> s + ";").collect(Collectors.joining())); @@ -544,7 +569,7 @@ public class NBCLIOptions { public String getProgressSpec() { ProgressSpec spec = parseProgressSpec(this.progressSpec);// sanity check if (spec.indicatorMode == IndicatorMode.console - && Level.INFO.isGreaterOrEqual(wantsConsoleLogLevel())) { + && Level.INFO.isGreaterOrEqual(wantsConsoleLogLevel())) { logger.warn("Console is already logging info or more, so progress data on console is suppressed."); spec.indicatorMode = IndicatorMode.logonly; } @@ -556,7 +581,7 @@ public class NBCLIOptions { configs.stream().map(LoggerConfig::getFilename).forEach(s -> { if (files.contains(s)) { logger.warn(s + " is included in " + configName + " more than once. It will only be included " + - "in the first matching config. Reorder your options if you need to control this."); + "in the first matching config. Reorder your options if you need to control this."); } files.add(s); }); @@ -613,6 +638,10 @@ public class NBCLIOptions { histoLoggerConfigs.add(String.format("%s:%s:%s",file,pattern,interval)); } + public boolean wantsWorkloads() { + return wantsWorkloads; + } + public static enum CmdType { start, start2, @@ -665,7 +694,7 @@ public class NBCLIOptions { public String toString() { return "type:" + cmdType + ";spec=" + cmdSpec - + ((cmdArgs != null) ? ";cmdArgs=" + cmdArgs.toString() : ""); + + ((cmdArgs != null) ? ";cmdArgs=" + cmdArgs.toString() : ""); } } @@ -689,8 +718,8 @@ public class NBCLIOptions { break; default: throw new RuntimeException( - LOG_HISTO + - " options must be in either 'regex:filename:interval' or 'regex:filename' or 'filename' format" + LOG_HISTO + + " options must be in either 'regex:filename:interval' or 'regex:filename' or 'filename' format" ); } } @@ -714,7 +743,7 @@ public class NBCLIOptions { switch (parts.length) { case 2: Unit.msFor(parts[1]).orElseThrow( - () -> new RuntimeException("Unable to parse progress indicator indicatorSpec '" + parts[1] + "'") + () -> new RuntimeException("Unable to parse progress indicator indicatorSpec '" + parts[1] + "'") ); progressSpec.intervalSpec = parts[1]; case 1: diff --git a/engine-cli/src/test/java/io/nosqlbench/engine/cli/TestNBCLIOptions.java b/engine-cli/src/test/java/io/nosqlbench/engine/cli/TestNBCLIOptions.java index 543f240af..b0c2cff55 100644 --- a/engine-cli/src/test/java/io/nosqlbench/engine/cli/TestNBCLIOptions.java +++ b/engine-cli/src/test/java/io/nosqlbench/engine/cli/TestNBCLIOptions.java @@ -1,9 +1,15 @@ package io.nosqlbench.engine.cli; +import io.nosqlbench.docsys.core.PathWalker; +import io.nosqlbench.virtdata.api.VirtDataResources; import org.testng.annotations.Test; +import java.net.URL; +import java.nio.file.Path; +import java.nio.file.Paths; import java.security.InvalidParameterException; import java.util.List; +import java.util.stream.Collectors; import static org.assertj.core.api.Assertions.assertThat; @@ -188,15 +194,53 @@ public class TestNBCLIOptions { } @Test - public void cqlIotYamlScenario() { + public void scenarioYaml() { NBCLIOptions opts = new NBCLIOptions(new String[]{ "scenario-test" }); List cmds = opts.getCommands(); } @Test - public void cqlIotYamlScenarioSchemaOnly() { + public void scenarioYamlCliArgs() { + NBCLIOptions opts = new NBCLIOptions(new String[]{ "scenario-test", "cycles=100"}); + List cmds = opts.getCommands(); + assertThat(cmds.get(0).getCmdSpec()).containsOnlyOnce("cycles=100"); + assertThat(cmds.get(0).getCmdSpec()).containsOnlyOnce("cycles="); + } + + @Test + public void scenarioYamlFilter() { NBCLIOptions opts = new NBCLIOptions(new String[]{ "scenario-test", "schema-only"}); List cmds = opts.getCommands(); } + @Test + public void scenarioYamlFilterCliArgs() { + NBCLIOptions opts = new NBCLIOptions(new String[]{ "scenario-test", "schema-only", "cycles=100"}); + List cmds = opts.getCommands(); + assertThat(cmds.get(0).getCmdSpec()).containsOnlyOnce("cycles=100"); + assertThat(cmds.get(0).getCmdSpec()).containsOnlyOnce("cycles="); + } + + @Test + public void listWorkloads() { + NBCLIOptions opts = new NBCLIOptions(new String[]{ "--list-workloads"}); + List cmds = opts.getCommands(); + assertThat(opts.wantsWorkloads()); + } + + + @Test + public void clTest() { + String dir= "activities/"; + URL resource = getClass().getClassLoader().getResource(dir); + assertThat(resource); + Path basePath = VirtDataResources.findPathIn(dir); + List yamlPathList = PathWalker.findAll(basePath).stream().filter(f -> f.toString().endsWith(".yaml")).collect(Collectors.toList()); + assertThat(yamlPathList); + } + + @Test + public void nbcli() { + NBCLI.main(new String[]{"--list-workloads"}); + } } diff --git a/engine-cli/src/test/resources/activities/scenario-test.yaml b/engine-cli/src/test/resources/activities/scenario-test.yaml index a223b75ce..7851d843b 100644 --- a/engine-cli/src/test/resources/activities/scenario-test.yaml +++ b/engine-cli/src/test/resources/activities/scenario-test.yaml @@ -1,4 +1,4 @@ -# nb -v run type=cql yaml=baselines/cql-iot tags=phase:schema host=dsehost +# nb -v run type=cql yaml=cql-iot tags=phase:schema host=dsehost scenarios: default: - run type=stdout yaml=scenario-test tags=phase:schema