mirror of
https://github.com/nosqlbench/nosqlbench.git
synced 2026-10-12 09:24:52 -05:00
fix param mutability bug, defer dryrun till full activity rendering
This commit is contained in:
1 parent
95e119d759
commit
f95fbfc049
6 files changed
+133
-4
No files matched your search
+5
-3
@@ -76,14 +76,17 @@ public class OpsLoader {
|
||||
if (srcuri != null) {
|
||||
logger.info("workload URI: '" + srcuri + "'");
|
||||
}
|
||||
Map<String, ?> expressionParams = params == null ? Map.of() : Map.copyOf(params);
|
||||
// Defensive copy so template processing never mutates caller-owned params
|
||||
Map<String, Object> mutableParams =
|
||||
(params == null) ? new java.util.LinkedHashMap<>() : new java.util.LinkedHashMap<>(params);
|
||||
Map<String, ?> expressionParams = Map.copyOf(mutableParams);
|
||||
|
||||
// Use TemplateContext to automatically manage template state lifecycle
|
||||
try (TemplateContext ctx = TemplateContext.enter()) {
|
||||
// PHASE 1: Rewrite TEMPLATE syntax to expr function calls
|
||||
// This converts TEMPLATE(k,v) and ${key:value} to expr paramOr() calls
|
||||
String templateRewritten = switch (fmt) {
|
||||
case jsonnet -> evaluateJsonnet(srcuri, params); // Jsonnet doesn't need template rewriting
|
||||
case jsonnet -> evaluateJsonnet(srcuri, mutableParams); // Jsonnet doesn't need template rewriting
|
||||
case yaml, json, inline, stmt -> TemplateRewriter.rewrite(sourceData);
|
||||
};
|
||||
|
||||
@@ -103,7 +106,6 @@ public class OpsLoader {
|
||||
Map<String, String> templateAccesses = ctx.getAccesses();
|
||||
templateAccesses.forEach((k, v) -> {
|
||||
layered.addTemplateVariable(k, v);
|
||||
params.remove(k);
|
||||
});
|
||||
|
||||
return layered;
|
||||
|
||||
+21
@@ -149,4 +149,25 @@ public class OpsLoaderTest {
|
||||
assertThat(result.getTemplateVariables()).containsKey("username");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTemplateProcessingDoesNotMutateParams() {
|
||||
String yaml = """
|
||||
ops:
|
||||
- stmt: "value is TEMPLATE(cmd_line_param,theDefault)"
|
||||
""";
|
||||
|
||||
Map<String, String> params = new HashMap<>();
|
||||
params.put("cmd_line_param", "TheProvidedParameter");
|
||||
|
||||
OpsDocList first = OpsLoader.loadString(yaml, OpTemplateFormat.yaml, params, null);
|
||||
assertThat(params).containsEntry("cmd_line_param", "TheProvidedParameter");
|
||||
assertThat(first.getStmtDocs().get(0).getOpTemplates().get(0).getStmt())
|
||||
.hasValue("value is TheProvidedParameter");
|
||||
|
||||
OpsDocList second = OpsLoader.loadString(yaml, OpTemplateFormat.yaml, params, null);
|
||||
assertThat(params).containsEntry("cmd_line_param", "TheProvidedParameter");
|
||||
assertThat(second.getStmtDocs().get(0).getOpTemplates().get(0).getStmt())
|
||||
.hasValue("value is TheProvidedParameter");
|
||||
}
|
||||
|
||||
}
|
||||
+4
-1
@@ -128,7 +128,10 @@ public class NBCLIScenarioPreprocessor {
|
||||
.first().orElseThrow();
|
||||
|
||||
// TODO: The yaml needs to be parsed with arguments from each command independently to support template vars
|
||||
OpsDocList scenariosYaml = OpsLoader.loadContent(yamlWithNamedScenarios, new LinkedHashMap<>(userProvidedParams));
|
||||
// Avoid triggering dryrun modes during scenario parsing; these should apply to the final activity load
|
||||
LinkedHashMap<String, String> paramsForScenarioParsing = new LinkedHashMap<>(userProvidedParams);
|
||||
paramsForScenarioParsing.remove("dryrun");
|
||||
OpsDocList scenariosYaml = OpsLoader.loadContent(yamlWithNamedScenarios, paramsForScenarioParsing);
|
||||
Scenarios scenarios = scenariosYaml.getDocScenarios();
|
||||
|
||||
String[] nameparts = scenarioName.split("\\.",2);
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 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.api.scenarios;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Probe used by NBCLIScenarioPreprocessorTest to ensure dryrun does not
|
||||
* trigger System.exit during scenario parsing.
|
||||
*/
|
||||
public class NBCLIScenarioPreprocessorDryrunProbe {
|
||||
public static void main(String[] args) {
|
||||
LinkedList<String> argv = new LinkedList<>();
|
||||
argv.add("cmdline_template");
|
||||
argv.add("the_scenario");
|
||||
argv.add("dryrun=exprs");
|
||||
|
||||
NBCLIScenarioPreprocessor.rewriteScenarioCommands(argv, List.of("src/test/resources"));
|
||||
|
||||
System.out.println("PROBE_OK");
|
||||
System.out.println("ARGS=" + String.join(" ", argv));
|
||||
}
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 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.api.scenarios;
|
||||
|
||||
import org.junit.jupiter.api.Tag;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@Tag("unit")
|
||||
public class NBCLIScenarioPreprocessorTest {
|
||||
|
||||
@Test
|
||||
public void rewriteScenarioCommands_shouldNotTriggerDryrunDuringScenarioParsing() throws Exception {
|
||||
String javaBin = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java";
|
||||
String classpath = System.getProperty("java.class.path");
|
||||
|
||||
ProcessBuilder pb = new ProcessBuilder(
|
||||
javaBin,
|
||||
"-cp",
|
||||
classpath,
|
||||
"io.nosqlbench.engine.api.scenarios.NBCLIScenarioPreprocessorDryrunProbe"
|
||||
);
|
||||
pb.directory(new File(System.getProperty("user.dir")));
|
||||
pb.redirectErrorStream(true);
|
||||
|
||||
Process p = pb.start();
|
||||
String output = new String(p.getInputStream().readAllBytes(), StandardCharsets.UTF_8);
|
||||
int exit = p.waitFor();
|
||||
|
||||
assertThat(exit).isEqualTo(0);
|
||||
assertThat(output).contains("PROBE_OK");
|
||||
assertThat(output).contains("cmd_line_param=firstone");
|
||||
assertThat(output).contains("dryrun=exprs");
|
||||
assertThat(output).contains("run");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
scenarios:
|
||||
the_scenario:
|
||||
the_activity: run driver=stdout tags==block:the_block threads==1 cycles==1 cmd_line_param=TEMPLATE(cmd_line_param, firstone)
|
||||
blocks:
|
||||
the_block:
|
||||
ops:
|
||||
the_only_op:
|
||||
stmt: |
|
||||
================================================
|
||||
The command-line-parameter is: "TEMPLATE(cmd_line_param, theDefault)".
|
||||
================================================
|
||||
Reference in new issue
Block a user