All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.fluxtion.compiler.validation.EventProcessorValidatorDriver Maven / Gradle / Ivy

package com.fluxtion.compiler.validation;

import com.fluxtion.runtime.EventProcessor;
import com.fluxtion.runtime.dataflow.MutableNumber;
import com.fluxtion.runtime.time.ClockStrategy;

import java.util.concurrent.atomic.LongAdder;
import java.util.function.BiPredicate;
import java.util.function.Supplier;
import java.util.stream.Stream;

/**
 * Validates an {@link EventProcessor} with a supplied {@link BiPredicate}. Events are dispatched into the processor
 * from a {@link Stream} source.
 *
 * @param  The output type of the sink
 */
public class EventProcessorValidatorDriver {
    private final EventProcessor eventProcessor;
    private final Stream>> validationStream;
    private final BiPredicate sinkValidator;
    private boolean useSyntheticTime;
    private boolean stopOnFirstFailure = true;
    private EXPECTED actualOutput;
    private final MutableNumber syntheticTime = new MutableNumber();
    private final LongAdder rowCount = new LongAdder();

    public EventProcessorValidatorDriver(
            EventProcessor eventProcessor,
            Stream>> validationStream,
            BiPredicate sinkValidator) {
        this(eventProcessor, validationStream, sinkValidator, false);
    }

    public EventProcessorValidatorDriver(
            EventProcessor eventProcessor,
            Stream>> validationStream,
            BiPredicate sinkValidator,
            boolean useSyntheticTime) {
        this.eventProcessor = eventProcessor;
        this.validationStream = validationStream;
        this.sinkValidator = sinkValidator;
        this.useSyntheticTime = useSyntheticTime;
        syntheticTime.setLongValue(0);
        rowCount.reset();
    }

    public boolean useSyntheticTime() {
        return useSyntheticTime;
    }

    public EventProcessorValidatorDriver useSyntheticTime(boolean useSyntheticTime) {
        this.useSyntheticTime = useSyntheticTime;
        return this;
    }

    public boolean stopOnFirstFailure() {
        return stopOnFirstFailure;
    }

    public EventProcessorValidatorDriver stopOnFirstFailure(boolean stopOnFirstFailure) {
        this.stopOnFirstFailure = stopOnFirstFailure;
        return this;
    }

    public void validate() {
        eventProcessor.init();
        if (useSyntheticTime) {
            eventProcessor.onEvent(ClockStrategy.registerClockEvent(syntheticTime::longValue));
        }
        validationStream.map(Supplier::get).forEach(this::validateRow);
    }

    private void validateRow(TestRowValidationRecord row) {
        if (useSyntheticTime) {
            syntheticTime.setLongValue(row.timeMillis());
        }
        eventProcessor.onEvent(row.inputEvent());
        EXPECTED expectedOutput = row.expected();
        if (expectedOutput != null && sinkValidator.test(eventProcessor, expectedOutput)) {
            throw new AssertionError("validation error on row:" + rowCount.longValue()
                    + " objects failed vaildation["
                    + expectedOutput
                    + "  ==> " + actualOutput
                    + "]"
            );
        }
        rowCount.increment();
        actualOutput = null;
    }

    static boolean objectsAreEqual(Object obj1, Object obj2) {
        if (obj1 == null) {
            return (obj2 == null);
        }
        return obj1.equals(obj2);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy