From 10f8d220bf57052646601abf13bbb7313548037d Mon Sep 17 00:00:00 2001 From: Richard Richter Date: Mon, 9 Mar 2020 15:30:26 +0100 Subject: [PATCH] TracerImpl decoupled from test + Tracer.setTemplateParametersCustomizer --- .../test/AbstractIntegrationTest.java | 19 +++-- .../evolveum/midpoint/task/api/Tracer.java | 17 +++- .../task/quartzimpl/tracing/TracerImpl.java | 81 ++++++++++--------- 3 files changed, 67 insertions(+), 50 deletions(-) diff --git a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/AbstractIntegrationTest.java b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/AbstractIntegrationTest.java index 0027d2f82a7..615ed3d0e9e 100644 --- a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/AbstractIntegrationTest.java +++ b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/AbstractIntegrationTest.java @@ -135,6 +135,9 @@ public abstract class AbstractIntegrationTest extends AbstractSpringTest protected static final Random RND = new Random(); + private static final String MACRO_TEST_NAME_TRACER_PARAM = "testName"; + private static final String MACRO_TEST_NAME_SHORT_TRACER_PARAM = "testNameShort"; + private static final float FLOAT_EPSILON = 0.001f; // Values used to check if something is unchanged or changed properly @@ -255,16 +258,14 @@ protected void postInitSystem(Task initTask, OperationResult initResult) throws * This implementation fully overrides version from {@link AbstractSpringTest}. */ @BeforeMethod - public void startTestContext(ITestResult testResult) { + public void startTestContext(ITestResult testResult) throws SchemaException { Class testClass = testResult.getMethod().getTestClass().getRealClass(); String testMethodName = testResult.getMethod().getMethodName(); - - displayTestTitle(testClass.getSimpleName() + "." + testMethodName); + String testName = testClass.getSimpleName() + "." + testMethodName; + displayTestTitle(testName); Task task = createTask(testMethodName); - // TODO inttest do we need that subresult? :-) (Virgo's brave new world) - // If this exist for some "optional richer tracing", why not switch it on with some System property? - // maybe it doesn't break tests, but changes traceability/maintenance? + // TODO inttest: add tracing facility - ideally without the need to create subresult // OperationResult rootResult = task.getResult(); // TracingProfileType tracingProfile = getTestMethodTracingProfile(); // CompiledTracingProfile compiledTracingProfile = tracingProfile != null ? @@ -278,8 +279,10 @@ public void startTestContext(ITestResult testResult) { // task.setResult(result); MidpointTestContextWithTask.create(testClass, testMethodName, task, task.getResult()); - // TODO inttest: remove after fix in TracerImpl - TestNameHolder.setCurrentTestName(contextName()); + tracer.setTemplateParametersCustomizer(params -> { + params.put(MACRO_TEST_NAME_TRACER_PARAM, testName); + params.put(MACRO_TEST_NAME_SHORT_TRACER_PARAM, testMethodName); + }); } /** diff --git a/repo/task-api/src/main/java/com/evolveum/midpoint/task/api/Tracer.java b/repo/task-api/src/main/java/com/evolveum/midpoint/task/api/Tracer.java index ea1d1852ce3..f90f86afbd1 100644 --- a/repo/task-api/src/main/java/com/evolveum/midpoint/task/api/Tracer.java +++ b/repo/task-api/src/main/java/com/evolveum/midpoint/task/api/Tracer.java @@ -7,11 +7,16 @@ package com.evolveum.midpoint.task.api; +import java.util.Map; +import java.util.function.Consumer; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + import com.evolveum.midpoint.schema.result.CompiledTracingProfile; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.xml.ns._public.common.common_3.TracingProfileType; -import org.jetbrains.annotations.Nullable; /** * @@ -21,8 +26,8 @@ public interface Tracer { /** * Stores trace to persistent storage (usually a file in "trace" directory). * - * @param task Task containing the context information necessary e.g. to derive name of the trace file. - * @param result Result that is to be serialized and stored. + * @param task Task containing the context information necessary e.g. to derive name of the trace file. + * @param result Result that is to be serialized and stored. * @param parentResult Parent result where this operation should be recorded (if any). */ void storeTrace(Task task, OperationResult result, @Nullable OperationResult parentResult); @@ -39,5 +44,11 @@ public interface Tracer { CompiledTracingProfile compileProfile(TracingProfileType profile, OperationResult result) throws SchemaException; + /** + * Sets customizer of tracer template parameters, replacing any previous one. + * This allows to inject custom parameters, for instance during test runs. + */ + void setTemplateParametersCustomizer(@NotNull Consumer> customizer); + //TracingLevelType getLevel(@NotNull TracingProfileType resolvedProfile, @NotNull Class traceClass); } diff --git a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/tracing/TracerImpl.java b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/tracing/TracerImpl.java index 94001b1a922..361dc356c68 100644 --- a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/tracing/TracerImpl.java +++ b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/tracing/TracerImpl.java @@ -7,6 +7,27 @@ package com.evolveum.midpoint.task.quartzimpl.tracing; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.charset.StandardCharsets; +import java.text.SimpleDateFormat; +import java.util.Objects; +import java.util.*; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.text.StringSubstitutor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + import com.evolveum.midpoint.common.configuration.api.MidpointConfiguration; import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.util.CloneUtil; @@ -18,7 +39,6 @@ import com.evolveum.midpoint.schema.result.CompiledTracingProfile; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; -import com.evolveum.midpoint.schema.util.TestNameHolder; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.task.api.TaskManager; import com.evolveum.midpoint.task.api.Tracer; @@ -31,25 +51,6 @@ import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; -import org.apache.commons.lang.StringUtils; -import org.apache.commons.text.StringSubstitutor; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.stereotype.Component; - -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.PrintWriter; -import java.nio.charset.StandardCharsets; -import java.text.SimpleDateFormat; -import java.util.*; -import java.util.Objects; -import java.util.stream.Collectors; /** * Manages tracing requests. @@ -58,11 +59,10 @@ public class TracerImpl implements Tracer, SystemConfigurationChangeListener { private static final Trace LOGGER = TraceManager.getTrace(TracerImpl.class); + private static final String MACRO_TIMESTAMP = "timestamp"; private static final String MACRO_OPERATION_NAME = "operationName"; private static final String MACRO_OPERATION_NAME_SHORT = "operationNameShort"; - private static final String MACRO_TEST_NAME = "testName"; - private static final String MACRO_TEST_NAME_SHORT = "testNameShort"; private static final String MACRO_FOCUS_NAME = "focusName"; private static final String MACRO_MILLISECONDS = "milliseconds"; private static final String MACRO_RANDOM = "random"; @@ -78,7 +78,7 @@ public class TracerImpl implements Tracer, SystemConfigurationChangeListener { @Qualifier("cacheRepositoryService") private transient RepositoryService repositoryService; - private SystemConfigurationType systemConfiguration; // can be null during some tests + private SystemConfigurationType systemConfiguration; // can be null during some tests private static final String OP_STORE_TRACE = TracerImpl.class.getName() + ".storeTrace"; @@ -87,6 +87,11 @@ public class TracerImpl implements Tracer, SystemConfigurationChangeListener { private static final String DEFAULT_FILE_NAME_PATTERN = "trace-%{timestamp}"; + public static final Consumer> DEFAULT_TEMPLATE_PARAMETERS_CUSTOMIZER = params -> { + }; + + @NotNull private Consumer> templateParametersCustomizer = DEFAULT_TEMPLATE_PARAMETERS_CUSTOMIZER; + @PostConstruct public void init() { systemConfigurationChangeDispatcher.registerListener(this); @@ -113,7 +118,7 @@ public void storeTrace(Task task, OperationResult result, @Nullable OperationRes if (!Boolean.FALSE.equals(tracingProfile.isCreateTraceFile())) { boolean zip = !Boolean.FALSE.equals(tracingProfile.isCompressOutput()); - Map templateParameters = createTemplateParameters(task, result); // todo evaluate lazily if needed + Map templateParameters = createTemplateParameters(result); // todo evaluate lazily if needed File file = createFileName(zip, tracingProfile, templateParameters); try { long start = System.currentTimeMillis(); @@ -282,7 +287,7 @@ private String findOrCreateEntry(PrismObject object) { } int newEntryId = maxEntryId + 1; LOGGER.trace("Inserting object as entry #{}:{}: {} [in {} ms]", dictionaryId, newEntryId, objectToStore, - System.currentTimeMillis()-started); + System.currentTimeMillis() - started); dictionary.beginEntry() .identifier(newEntryId) @@ -321,7 +326,7 @@ private PrismObject stripFetchResult(PrismObject extractDictionary(partialResult, extractingVisitor)); } - private Map createTemplateParameters(Task task, OperationResult result) { + private Map createTemplateParameters(OperationResult result) { Map rv = new HashMap<>(); SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS"); rv.put(MACRO_TIMESTAMP, df.format(new Date())); String operationName = result.getOperation(); rv.put(MACRO_OPERATION_NAME, operationName); rv.put(MACRO_OPERATION_NAME_SHORT, shorten(operationName)); - String testName; - // TODO inttest: subclass TracerImpl in test scope with change here (use template method) - if (TestNameHolder.getCurrentTestName() != null) { - testName = TestNameHolder.getCurrentTestName(); - } else { - testName = task.getResult().getOperation(); - } - rv.put(MACRO_TEST_NAME, testName); // e.g. com.evolveum.midpoint.model.intest.TestIteration.test532GuybrushModifyDescription or simply TestIteration.test532GuybrushModifyDescription - rv.put(MACRO_TEST_NAME_SHORT, shorten(testName)); rv.put(MACRO_FOCUS_NAME, getFocusName(result)); rv.put(MACRO_MILLISECONDS, getMilliseconds(result)); - rv.put(MACRO_RANDOM, String.valueOf((long) (Math.random() * 1000000000000000L))); + rv.put(MACRO_RANDOM, String.valueOf((long) (Math.random() * 1_000_000_000_000_000L))); + templateParametersCustomizer.accept(rv); return rv; } + @Override + public void setTemplateParametersCustomizer( + @NotNull Consumer> customizer) { + templateParametersCustomizer = Objects.requireNonNull(customizer, "templateParametersCustomizer"); + } + private String shorten(String qualifiedName) { if (qualifiedName != null) { int secondLastDotIndex = StringUtils.lastOrdinalIndexOf(qualifiedName, ".", 2); - return secondLastDotIndex >= 0 ? qualifiedName.substring(secondLastDotIndex+1) : qualifiedName; + return secondLastDotIndex >= 0 ? qualifiedName.substring(secondLastDotIndex + 1) : qualifiedName; } else { return null; } @@ -471,7 +474,7 @@ private TracingProfileType getResolvedProfile(String ref, TracingConfigurationTy } resolutionPath.add(ref); TracingProfileType profile = findProfile(ref, tracingConfiguration); - resolutionPath.remove(resolutionPath.size()-1); + resolutionPath.remove(resolutionPath.size() - 1); TracingProfileType rv = resolveProfile(profile, tracingConfiguration, resolutionPath); LOGGER.info("Resolved '{}' into:\n{}", ref, rv.asPrismContainerValue().debugDump()); return rv;