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

com.teamscale.service.testimpact.prioritization.PrioritizableTestCluster Maven / Gradle / Ivy

The newest version!
package com.teamscale.service.testimpact.prioritization;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.conqat.engine.sourcecode.coverage.TestWithClusterId;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.teamscale.commons.lang.ToStringHelpers;
import com.teamscale.index.testimpact.MethodId;

/**
 * A {@link PrioritizableTestCluster} represents an ordered {@link List} of
 * {@link PrioritizableTest}s which should be executed together to avoid overhead. The order of the
 * {@link PrioritizableTest}s is determined by the prioritization of the {@link PrioritizableTest}s
 * w.r.t. to each other.
 *
 * A {@link PrioritizableTestCluster} assumes that possibly resource intensive setup or teardown
 * operations (e.g. a class containing a method annotated with {@code BeforeClass} in JUnit4 or
 * {@code BeforeAll} in JUnit5) can be executed once for a {@link PrioritizableTestCluster} instead
 * of executing them for each {@link PrioritizableTest}.
 */
public class PrioritizableTestCluster extends PrioritizableTestBase {

	private static final long serialVersionUID = 1L;

	/** The name of the JSON property name for {@link #clusterId}. */
	private static final String CLUSTER_ID_PROPERTY = "clusterId";

	/** The name of the JSON property name for {@link #tests}. */
	private static final String TESTS_PROPERTY = "tests";

	/**
	 * The unique cluster id to which all {@link PrioritizableTest}s belong.
	 *
	 * @see TestWithClusterId#clusterId
	 */
	@JsonProperty(CLUSTER_ID_PROPERTY)
	private final String clusterId;

	/** The {@link PrioritizableTest}s in this cluster. */
	@JsonProperty(TESTS_PROPERTY)
	private final List tests;

	@JsonCreator
	private PrioritizableTestCluster(@JsonProperty(CLUSTER_ID_PROPERTY) String clusterId,
			@JsonProperty(TESTS_PROPERTY) List tests) {
		super(tests.stream().flatMap(test -> test.getChangedMethodLocations().stream()).collect(Collectors.toSet()));
		this.clusterId = clusterId;
		this.tests = new ArrayList<>(tests);
	}

	/**
	 * Creates a prioritizable test cluster. Since the operations performed here cannot be used for Json
	 * creation, test clusters that are intended to be used for prioritization need to created with
	 * this.
	 */
	public static PrioritizableTestCluster create(String clusterId, List tests) {
		return new PrioritizableTestCluster(clusterId, tests);
	}

	/** @see #clusterId */
	public String getClusterId() {
		return clusterId;
	}

	/** @see #tests */
	public List getTests() {
		return Collections.unmodifiableList(tests);
	}

	/**
	 * Sets the tests within this cluster and update corresponding values to reflect these test changes.
	 */
	public void updateTestsInCluster(List tests, Set methodsToTest) {
		this.tests.clear();
		this.tests.addAll(tests);
		// reset multiple values based on new tests within cluster
		durationInMs = null;
		coveredChangedMethods.clear();
		initAdditionallyCoveredMethods(methodsToTest);
		coveredMethods = this.tests.stream().flatMap(test -> test.getCoveredMethods().stream())
				.collect(Collectors.toSet());
	}

	@Override
	public Set getSelectionReasons() {
		return tests.stream().flatMap(test -> test.getSelectionReasons().stream()).collect(Collectors.toSet());
	}

	/**
	 * Lazily instantiated set of the union of all methods covered by the {@link #tests}. Needed because
	 * the {@link #tests} in general don't contain their covered methods when passed to the constructor.
	 */
	@Override
	public Set getCoveredMethods() {
		if (coveredMethods == null) {
			coveredMethods = tests.stream().flatMap(test -> test.getCoveredMethods().stream())
					.collect(Collectors.toSet());
		}
		return coveredMethods;
	}

	@Override
	public long getDurationInMs(long durationValueIfNotSet) {
		if (durationInMs == null) {
			durationInMs = 0L;
			for (PrioritizableTest test : tests) {
				durationInMs += test.getDurationInMs(10000);
			}
		}

		return durationInMs;
	}

	/**
	 * Used for testing only.
	 */
	@Override
	public String toString() {
		return ToStringHelpers.toReflectiveStringHelper(this).toString();
	}

	@Override
	public String getIdentifier() {
		return clusterId;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy