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

com.xlrit.gears.runner.run.Driver Maven / Gradle / Ivy

There is a newer version: 1.17.1
Show newest version
package com.xlrit.gears.runner.run;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.xlrit.gears.runner.runnertarget.GenerateRunnerTarget;
import com.xlrit.gears.runner.runnertarget.GraphQLRunnerTarget;
import com.xlrit.gears.runner.runnertarget.RunnerTarget;
import com.xlrit.gears.runner.runnertarget.SelenideRunnerTarget;
import com.xlrit.gears.runner.scenario.RunnerTargetScenarioVisitor;
import com.xlrit.gears.runner.scenario.ScenarioLexer;
import com.xlrit.gears.runner.scenario.ScenarioParser;
import com.xlrit.gears.runner.utils.GraphQLUtils;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;

import java.io.*;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

public class Driver {
	private final List actions = new ArrayList<>();
	private RunnerTarget runnerTarget;

	public void run(String[] args) {
		Instant start = Instant.now();
		Config config = handleArgs(args);

		File dataDir = getDir(config.dataDir);
		File scenarioDir = getDir(config.scenarioDir);

		System.out.printf("Data directory: %s%n", dataDir.getAbsolutePath());
		System.out.printf("Scenario directory: %s%n", scenarioDir.getAbsolutePath());

		switch (config.runnerTarget) {
			case "graphql"  -> runnerTarget = new GraphQLRunnerTarget(config);
			case "selenide" -> runnerTarget = new SelenideRunnerTarget(config, true);
			case "generate" -> runnerTarget = new GenerateRunnerTarget(config);
			default -> throw new IllegalArgumentException(
					String.format("Unknown runnertarget: %s", config.runnerTarget)
			);
		}
		int loadCounter = 1;
		int scenarioCount = 0;
		int failCount = 0;
		for (DriverAction action : actions) {
			switch (action.type()) {
				case LOAD -> {
					if (config.dryrun) {
						List dataFiles = GraphQLUtils.listFilteredFiles(dataDir, action.pattern(), "sql");
						for (var dataFile : dataFiles) {
							System.out.printf(" - Loading data from %s%n", dataFile.getPath());
						}
					} else {
						System.out.printf(" - Loading data from %s%n", action.pattern());
						runnerTarget.scenarioStart(String.format("loadData%d", loadCounter++));
						runnerTarget.loadData(dataDir.getPath(), action.pattern());
						runnerTarget.scenarioFinish();
					}
				}
				case RUN -> {
					List scenarios = GraphQLUtils.listFilteredFiles(scenarioDir, action.pattern(), "scenario");
					for (File scenario : scenarios) {
						scenarioCount++;
						System.out.printf(" - Running scenario from %s%n", scenario.getName());
						if (config.dryrun) continue;
						runnerTarget.scenarioStart(getScenarioName(scenario.getName()));
						var error = runScenario(scenario);
						runnerTarget.scenarioFinish();
						error.ifPresent(s -> System.out.printf("Failure for reason: %s%n", s));
						if (error.isPresent()) failCount++;
					}
				}
			}
		}
		runnerTarget.finish();
		long durationMillis = Instant.now().toEpochMilli() - start.toEpochMilli();
		System.out.printf("Ran %d scenarios with %d failures in %d.%d seconds",
				scenarioCount, failCount, durationMillis / 1000, durationMillis % 1000);
	}

	private File getDir(String config) {
		File directory = new File(config);
		if (!directory.exists()) {
			throw new IllegalArgumentException(
					String.format("Directory not found: %s", directory.getAbsolutePath())
			);
		} else if (!directory.isDirectory()) {
			throw new IllegalArgumentException(
					String.format("File is not a directory: %s", directory.getAbsolutePath())
			);
		}
		return directory;
	}

	private String getScenarioName(String scenarioFileName) {
		String[] split = scenarioFileName.split("\\.");
		if (split.length == 1) return scenarioFileName;
		else {
			return String.join("_", Arrays.copyOfRange(split, 0, split.length - 1));
		}
	}

	private Optional runScenario(File scenarioFile) {
		try {
			InputStream is = new FileInputStream(scenarioFile);
			ScenarioLexer lexer = new ScenarioLexer(CharStreams.fromStream(is));
			CommonTokenStream tokens = new CommonTokenStream(lexer);
			ScenarioParser parser = new ScenarioParser(tokens);
			ParseTree tree = parser.startStatements();
			List errors = tree.accept(new RunnerTargetScenarioVisitor(runnerTarget));
			if (errors.isEmpty()) return Optional.empty();
			else return Optional.of(errors.get(0).getMessage());
		} catch (IOException e) {
			return Optional.of(e.getMessage());
		}
	}

	private Config handleArgs(String[] args) {
		Config config = new Config();
		for (int i = 0; i < args.length; i++) {
			switch (args[i]) {
				case "--config" -> {
					checkPresent(args.length, i, "Config flag given but no config file specified");
					ObjectMapper om = new ObjectMapper();
					try {
						config.readJson(om.readTree(new File(args[i + 1])));
						i++;
					} catch (IOException e) {
						throw new IllegalArgumentException(
								String.format("Config file %s could not be read: %s",
										args[i + 1],
										e.getMessage()
								)
						);
					}
				}
				case "--endpoint" -> {
					checkPresent(args.length, i, "Endpoint flag given but no endpoint specified");
					config.endpoint = args[i + 1];
					i++;
				}
				case "--timeout-millis" -> {
					checkPresent(args.length, i, "Timeout flag given but no timeout specified");
					try {
						config.timeoutMillis = Integer.parseInt(args[i + 1]);
						i++;
					} catch (NumberFormatException e) {
						throw new IllegalArgumentException(
								String.format("%s is not an integer", args[i + 1])
						);
					}
				}
				case "--load" -> {
					checkPresent(args.length, i, "Load flag given but no file pattern specified");
					String unquotedPattern = unquoteIfQuoted(args[i + 1]);
					actions.add(new DriverAction(unquotedPattern, DriverActionType.LOAD));
					i++;
				}
				case "--run" -> {
					checkPresent(args.length, i, "Run flag given but no file pattern specified");
					String unquotedPattern = unquoteIfQuoted(args[i + 1]);
					actions.add(new DriverAction(unquotedPattern, DriverActionType.RUN));
					i++;
				}
				case "--dry-run" -> config.dryrun = true;
				case "--headless" -> config.headless = true;
				case "--target" -> {
					checkPresent(args.length, i, "Target flag given but no target specified");
					config.runnerTarget = args[i + 1];
					i++;
				}
				case "--wait-millis" -> {
					checkPresent(args.length, i, "Waitmillis flag given but no amount specified");
					try {
						config.waitMillis = Integer.parseInt(args[i + 1]);
						i++;
					} catch (NumberFormatException e) {
						throw new IllegalArgumentException(
								String.format("%s is not an integer", args[i + 1])
						);
					}
				}
				default -> throw new IllegalArgumentException(
						String.format("Unknown command line argument: %s", args[i])
				);
			}
		}
		return config;
	}

	private String unquoteIfQuoted(String string) {
		if (string.length() >= 2
				&& string.startsWith("'")
				&& string.endsWith("'")) {
			return string.substring(1, string.length() - 1);
		}
		return string;
	}

	private void checkPresent(int argc, int i, String message) {
		if (i + 1 == argc) {
			throw new IllegalArgumentException(message);
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy