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

com.teamscale.test_impacted.engine.InternalImpactedTestEngine Maven / Gradle / Ivy

Go to download

A JUnit 5 engine that handles retrieving impacted tests from Teamscale and organizes their execution

There is a newer version: 34.2.0
Show newest version
package com.teamscale.test_impacted.engine;

import com.teamscale.report.testwise.model.TestExecution;
import com.teamscale.test_impacted.commons.LoggerUtils;
import com.teamscale.test_impacted.engine.executor.AvailableTests;
import com.teamscale.test_impacted.engine.executor.ITestSorter;
import com.teamscale.test_impacted.engine.executor.TeamscaleAgentNotifier;
import com.teamscale.test_impacted.engine.executor.TestwiseCoverageCollectingExecutionListener;
import com.teamscale.test_impacted.test_descriptor.ITestDescriptorResolver;
import com.teamscale.test_impacted.test_descriptor.TestDescriptorResolverRegistry;
import com.teamscale.test_impacted.test_descriptor.TestDescriptorUtils;
import org.junit.platform.engine.EngineDiscoveryRequest;
import org.junit.platform.engine.ExecutionRequest;
import org.junit.platform.engine.TestDescriptor;
import org.junit.platform.engine.TestEngine;
import org.junit.platform.engine.UniqueId;
import org.junit.platform.engine.support.descriptor.EngineDescriptor;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.ServiceLoader;
import java.util.logging.Logger;

import static com.teamscale.test_impacted.engine.ImpactedTestEngine.ENGINE_ID;

/**
 * Test engine called internally to allow testing without needing a {@link ServiceLoader} for {@link TestEngine} setup.
 */
class InternalImpactedTestEngine {

	private static final Logger LOGGER = LoggerUtils.getLogger(InternalImpactedTestEngine.class);

	private final TestEngineRegistry testEngineRegistry;

	private final ITestSorter testSorter;

	private final TeamscaleAgentNotifier teamscaleAgentNotifier;

	private final TestDataWriter testDataWriter;

	private final String partition;

	InternalImpactedTestEngine(ImpactedTestEngineConfiguration configuration, String partition) {
		this.testEngineRegistry = configuration.testEngineRegistry;
		this.testSorter = configuration.testSorter;
		this.testDataWriter = configuration.testDataWriter;
		this.teamscaleAgentNotifier = configuration.teamscaleAgentNotifier;
		this.partition = partition;
	}

	/**
	 * Performs test discovery by aggregating the result of all {@link TestEngine}s from the {@link TestEngineRegistry}
	 * in a single engine {@link TestDescriptor}.
	 */
	TestDescriptor discover(EngineDiscoveryRequest discoveryRequest, UniqueId uniqueId) {
		EngineDescriptor engineDescriptor = new EngineDescriptor(uniqueId, "Teamscale Impacted Tests");

		LOGGER.fine(() -> "Starting test discovery for engine " + ENGINE_ID);

		for (TestEngine delegateTestEngine : testEngineRegistry) {
			LOGGER.fine(() -> "Starting test discovery for delegate engine: " + delegateTestEngine.getId());
			TestDescriptor delegateEngineDescriptor = delegateTestEngine.discover(discoveryRequest,
					UniqueId.forEngine(delegateTestEngine.getId()));

			engineDescriptor.addChild(delegateEngineDescriptor);
		}

		LOGGER.fine(() -> "Discovered test descriptor for engine " + ENGINE_ID + ":\n" + TestDescriptorUtils
				.getTestDescriptorAsString(engineDescriptor));

		return engineDescriptor;
	}

	/**
	 * Executes the request by requesting execution of the {@link TestDescriptor} children aggregated in
	 * {@link #discover(EngineDiscoveryRequest, UniqueId)} with the corresponding {@link TestEngine}.
	 */
	void execute(ExecutionRequest request) {
		TestDescriptor rootTestDescriptor = request.getRootTestDescriptor();
		AvailableTests availableTests = TestDescriptorUtils.getAvailableTests(rootTestDescriptor, partition);

		LOGGER.fine(() -> "Starting selection and sorting " + ENGINE_ID + ":\n" + TestDescriptorUtils
				.getTestDescriptorAsString(rootTestDescriptor));

		testSorter.selectAndSort(rootTestDescriptor);

		LOGGER.fine(() -> "Starting execution of request for engine " + ENGINE_ID + ":\n" + TestDescriptorUtils
				.getTestDescriptorAsString(rootTestDescriptor));

		List testExecutions = executeTests(request, rootTestDescriptor);

		testDataWriter.dumpTestExecutions(testExecutions);
		testDataWriter.dumpTestDetails(availableTests.getTestList());
		teamscaleAgentNotifier.testRunEnded();
	}

	private List executeTests(ExecutionRequest request, TestDescriptor rootTestDescriptor) {
		List testExecutions = new ArrayList<>();
		for (TestDescriptor engineTestDescriptor : rootTestDescriptor.getChildren()) {
			Optional engineId = engineTestDescriptor.getUniqueId().getEngineId();
			if (!engineId.isPresent()) {
				LOGGER.severe(
						() -> "Engine ID for test descriptor " + engineTestDescriptor + " not present. Skipping execution of the engine.");
				continue;
			}

			TestEngine testEngine = testEngineRegistry.getTestEngine(engineId.get());
			ITestDescriptorResolver testDescriptorResolver = TestDescriptorResolverRegistry
					.getTestDescriptorResolver(testEngine.getId());
			TestwiseCoverageCollectingExecutionListener executionListener =
					new TestwiseCoverageCollectingExecutionListener(teamscaleAgentNotifier,
							testDescriptorResolver,
							request.getEngineExecutionListener());

			testEngine.execute(new ExecutionRequest(engineTestDescriptor, executionListener,
					request.getConfigurationParameters()));

			testExecutions.addAll(executionListener.getTestExecutions());
		}
		return testExecutions;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy