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

io.hyperfoil.core.parser.BenchmarkParser Maven / Gradle / Ivy

There is a newer version: 0.27.1
Show newest version
/*
 * Copyright 2018 Red Hat Inc. and/or its affiliates and other contributors
 * as indicated by the @authors tag. All rights reserved.
 * See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * 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.hyperfoil.core.parser;

import io.hyperfoil.api.config.Benchmark;
import io.hyperfoil.api.config.BenchmarkBuilder;
import io.hyperfoil.api.config.BenchmarkData;
import io.hyperfoil.core.util.Util;
import io.vertx.core.logging.Logger;
import io.vertx.core.logging.LoggerFactory;

import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.events.DocumentEndEvent;
import org.yaml.snakeyaml.events.DocumentStartEvent;
import org.yaml.snakeyaml.events.Event;
import org.yaml.snakeyaml.events.MappingEndEvent;
import org.yaml.snakeyaml.events.MappingStartEvent;
import org.yaml.snakeyaml.events.SequenceEndEvent;
import org.yaml.snakeyaml.events.SequenceStartEvent;
import org.yaml.snakeyaml.events.StreamEndEvent;
import org.yaml.snakeyaml.events.StreamStartEvent;

import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.util.Iterator;

public class BenchmarkParser extends AbstractMappingParser {
    private static final Logger log = LoggerFactory.getLogger(BenchmarkParser.class);
    private static final BenchmarkParser INSTANCE = new BenchmarkParser();
    private static final boolean DEBUG_PARSER = Boolean.getBoolean("io.hyperfoil.parser.debug");

    public static BenchmarkParser instance() {
        return INSTANCE;
    }

    private BenchmarkParser() {
        register("$schema", new PropertyParser.String<>(this::checkSchema));
        register("name", new PropertyParser.String<>(BenchmarkBuilder::name));
        register("agents", new AgentsParser());
        register("ergonomics", new ErgonomicsParser());
        register("http", new HttpParser());
        register("phases", new PhasesParser());
        register("threads", new PropertyParser.Int<>(BenchmarkBuilder::threads));
        register("statisticsCollectionPeriod", new PropertyParser.Int<>(BenchmarkBuilder::statisticsCollectionPeriod));
        // simplified single-phase definition
        register("usersPerSec", new PropertyParser.Double<>((bb, value) -> bb.singleConstantPerSecPhase().usersPerSec(value)));
        register("duration", new PropertyParser.String<>((bb, value) -> bb.singleConstantPerSecPhase().duration(value)));
        register("maxDuration", new PropertyParser.String<>((bb, value) -> bb.singleConstantPerSecPhase().maxDuration(value)));
        register("maxSessionsEstimate", new PropertyParser.Int<>((bb, value) -> bb.singleConstantPerSecPhase().maxSessionsEstimate(value)));
        register("scenario", (ctx, target) -> new ScenarioParser().parse(ctx, target.singleConstantPerSecPhase().scenario()));
    }

    private void checkSchema(BenchmarkBuilder builder, String schema) {
        if (schema.startsWith("http") && !schema.startsWith("http://hyperfoil.io/schema") &&
              !schema.startsWith("https://hyperfoil.io/schema")) {
            log.warn("Unexpected schema: should start with `http://hyperfoil.io/schema`!");
        }
    }

    public Benchmark buildBenchmark(String source, BenchmarkData data) throws ParserException {
        Yaml yaml = new Yaml();

        Iterator events = yaml.parse(new StringReader(source)).iterator();
        if (DEBUG_PARSER) {
            events = new DebugIterator<>(events);
        }
        Context ctx = new Context(events);

        ctx.expectEvent(StreamStartEvent.class);
        ctx.expectEvent(DocumentStartEvent.class);

        //instantiate new benchmark builder
        BenchmarkBuilder benchmarkBuilder = new BenchmarkBuilder(source, data);
        parse(ctx, benchmarkBuilder);

        ctx.expectEvent(DocumentEndEvent.class);
        ctx.expectEvent(StreamEndEvent.class);

        return benchmarkBuilder.build();
    }

    public Benchmark buildBenchmark(InputStream inputStream, BenchmarkData data) throws ParserException, IOException {
        return buildBenchmark(Util.toString(inputStream), data);
    }

    private static class DebugIterator implements Iterator {
        private final Iterator it;
        private String indent = "";

        private DebugIterator(Iterator it) {
            this.it = it;
        }

        @Override
        public boolean hasNext() {
            return it.hasNext();
        }

        @Override
        public T next() {
            T event = it.next();
            if (event instanceof MappingEndEvent || event instanceof SequenceEndEvent) {
                indent = indent.substring(2);
            }
            StackTraceElement[] stackTrace = new Exception().fillInStackTrace().getStackTrace();
            System.out.println(indent + event + " fetched from " + stackTrace[1] + "\t" + stackTrace[2] + "\t" + stackTrace[3]);
            if (event instanceof MappingStartEvent || event instanceof SequenceStartEvent) {
                indent += "| ";
            }
            return event;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy