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

org.moditect.jfrunit.ExpectedEvent Maven / Gradle / Ivy

The newest version!
/*
 * SPDX-License-Identifier: Apache-2.0
 *
 * Copyright 2020 - 2021 The JfrUnit authors.
 *
 * 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
 *
 *     https://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 org.moditect.jfrunit;

import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Predicate;

import jdk.jfr.consumer.RecordedEvent;
import jdk.jfr.consumer.RecordedFrame;
import jdk.jfr.consumer.RecordedStackTrace;

public class ExpectedEvent implements Predicate {

    private String name;
    private Map, Object> withProps = new HashMap<>();
    private List> hasProps = new ArrayList<>();
    private List> hasNotProps = new ArrayList<>();
    private List frames = new ArrayList<>();

    private ExpectedEvent(String name) {
        this.name = name;
    }

    public static ExpectedEvent event(String name) {
        return new ExpectedEvent(name);
    }

    public static ExpectedEvent event(JfrEventType jfrEventType) {
        return new ExpectedEvent(jfrEventType.getName());
    }

    /* default */ static boolean matches(ExpectedEvent expectedEvent, RecordedEvent recordedEvent) {
        if (expectedEvent.getName() != null
                && !recordedEvent.getEventType().getName().equals(expectedEvent.getName())) {
            return false;
        }

        if (!expectedEvent.getHasProps().isEmpty()) {
            for (Attribute attribute : expectedEvent.getHasProps()) {
                if (!hasPropertyMatching(recordedEvent, attribute.getName()))
                    return false;
            }
        }

        if (!expectedEvent.getHasNotProps().isEmpty()) {
            for (Attribute attribute : expectedEvent.getHasNotProps()) {
                if (hasPropertyMatching(recordedEvent, attribute.getName())) {
                    return false;
                }
            }
        }

        if (!expectedEvent.getWithProps().isEmpty()) {
            for (Map.Entry, Object> prop : expectedEvent.getWithProps().entrySet()) {
                if (!withPropertyMatching(recordedEvent, prop.getKey().getName(), prop.getValue())) {
                    return false;
                }
            }
        }

        if (!expectedEvent.getFrames().isEmpty()) {
            RecordedStackTrace stackTrace = recordedEvent.getStackTrace();
            if (stackTrace == null) {
                return false;
            }
            for (ExpectedStackFrame expectedStackFrame : expectedEvent.getFrames()) {
                List recordedFrames = stackTrace.getFrames();
                if (recordedFrames.stream().noneMatch(expectedStackFrame::test)) {
                    return false;
                }
            }
        }

        return true;
    }

    private static boolean hasPropertyMatching(RecordedEvent recordedEvent, String name) {
        if (!recordedEvent.hasField(name)) {
            return false;
        }

        Object value = recordedEvent.getValue(name);
        return value != null;
    }

    private static boolean withPropertyMatching(RecordedEvent recordedEvent, String name, Object value) {
        if (!recordedEvent.hasField(name)) {
            return false;
        }

        if ("objectClass".equalsIgnoreCase(name) && !(value instanceof ExpectedClass)) {
            return Objects.equals(recordedEvent.getClass("objectClass").getName(), value.toString());
        }

        if (value instanceof Duration) {
            return Objects.equals(recordedEvent.getDuration(name), value);
        }
        else if (value instanceof String) {
            return Objects.equals(recordedEvent.getString(name), value);
        }
        else if (value instanceof Boolean) {
            return Objects.equals(recordedEvent.getBoolean(name), value);
        }
        else if (value instanceof Byte) {
            return Objects.equals(recordedEvent.getByte(name), value);
        }
        else if (value instanceof Character) {
            return Objects.equals(recordedEvent.getChar(name), value);
        }
        else if (value instanceof Double) {
            return Objects.equals(recordedEvent.getDouble(name), value);
        }
        else if (value instanceof Float) {
            return Objects.equals(recordedEvent.getFloat(name), value);
        }
        else if (value instanceof Integer) {
            return Objects.equals(recordedEvent.getInt(name), value);
        }
        else if (value instanceof Long) {
            return Objects.equals(recordedEvent.getLong(name), value);
        }
        else if (value instanceof Short) {
            return Objects.equals(recordedEvent.getShort(name), value);
        }
        else if (value instanceof Instant) {
            return Objects.equals(recordedEvent.getInstant(name), value);
        }
        else if (value instanceof ExpectedClass) {
            return ((ExpectedClass) value).test(recordedEvent.getClass(name));
        }
        else if (value instanceof ExpectedThread) {
            return ((ExpectedThread) value).test(recordedEvent.getThread(name));
        }
        else {
            throw new IllegalArgumentException(String.format("Unsupported property type: %s, %s", name, value));
        }
    }

    public String getName() {
        return name;
    }

    public Map, Object> getWithProps() {
        return withProps;
    }

    public List> getHasProps() {
        return hasProps;
    }

    public List> getHasNotProps() {
        return hasNotProps;
    }

    public List getFrames() {
        return frames;
    }

    public  ExpectedEvent with(Attribute attribute, B value) {
        this.withProps.put(attribute, value);
        return this;
    }

    public ExpectedEvent with(String name, Object value) {
        this.withProps.put(new Attribute<>(name), value);
        return this;
    }

    public ExpectedEvent has(Attribute attribute) {
        this.hasProps.add(attribute);
        return this;
    }

    public ExpectedEvent has(String name) {
        this.hasProps.add(new Attribute<>(name));
        return this;
    }

    public ExpectedEvent hasNot(Attribute attribute) {
        this.hasNotProps.add(attribute);
        return this;
    }

    public ExpectedEvent hasNot(String name) {
        this.hasNotProps.add(new Attribute<>(name));
        return this;
    }

    public ExpectedEvent containStackFrame(ExpectedStackFrame value) {
        this.frames.add(value);
        return this;
    }

    @Override
    public boolean test(RecordedEvent recordedEvent) {
        return matches(this, recordedEvent);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy