/* * Copyright (c) 2015 the original author or authors. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Etienne Studer & Donát Csikós (Gradle Inc.) - initial API and implementation and initial documentation */ package org.eclipse.buildship.ui.view.execution; import java.util.List; import org.gradle.tooling.events.test.JvmTestKind; import org.gradle.tooling.events.test.JvmTestOperationDescriptor; import org.gradle.tooling.events.test.TestFailureResult; import org.gradle.tooling.events.test.TestFinishEvent; import org.gradle.tooling.events.test.TestOperationDescriptor; import com.google.common.base.Function; import com.google.common.base.Preconditions; import com.google.common.base.Predicate; import com.google.common.collect.ImmutableList; import org.eclipse.core.runtime.jobs.IJobChangeEvent; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.runtime.jobs.JobChangeAdapter; import org.eclipse.jface.action.Action; import org.eclipse.buildship.core.configuration.RunConfiguration; import org.eclipse.buildship.core.launch.RunGradleTestLaunchRequestJob; import org.eclipse.buildship.ui.PluginImage.ImageState; import org.eclipse.buildship.ui.PluginImages; import org.eclipse.buildship.ui.i18n.UiMessages; import org.eclipse.buildship.ui.util.gradle.GradleUtils; /** * Reruns the build represented by the target {@link org.eclipse.buildship.ui.view.execution.ExecutionPage}. * <p/> * Note: we listen for removals of {@code ILaunchConfiguration} instances even though not every {@code ProcessDescription} implementation * is necessarily backed by a launch configuration. This means that in the worst case, {@code ProcessDescription#isRerunnable()} is invoked * unnecessarily (which does no harm). */ public final class RerunFailedTestsAction extends Action { private final ExecutionPage page; public RerunFailedTestsAction(ExecutionPage executionPage) { this.page = Preconditions.checkNotNull(executionPage); setToolTipText(UiMessages.Action_RerunFailedTests_Tooltip); setImageDescriptor(PluginImages.RERUN_FAILED_TESTS.withState(ImageState.ENABLED).getImageDescriptor()); setDisabledImageDescriptor(PluginImages.RERUN_FAILED_TESTS.withState(ImageState.DISABLED).getImageDescriptor()); registerJobChangeListener(); } private void registerJobChangeListener() { Job job = this.page.getProcessDescription().getJob(); job.addJobChangeListener(new JobChangeAdapter() { @Override public void done(IJobChangeEvent event) { update(); } }); update(); } private void update() { setEnabled(this.page.getProcessDescription().getJob().getState() == Job.NONE && !collectFailedTests().isEmpty()); } @Override public void run() { List<TestOperationDescriptor> failedTests = collectFailedTests(); List<TestOperationDescriptor> filteredFailedTests = GradleUtils.filterChildren(failedTests); RunConfiguration runConfig = this.page.getProcessDescription().getRunConfig(); RunGradleTestLaunchRequestJob job = new RunGradleTestLaunchRequestJob(filteredFailedTests, runConfig); job.schedule(); } private ImmutableList<TestOperationDescriptor> collectFailedTests() { return this.page.filterTreeNodes(new Predicate<OperationItem>() { @Override public boolean apply(OperationItem operationItem) { return isFailedJvmTest(operationItem); } }).transform(new Function<OperationItem, TestOperationDescriptor>() { @Override public TestOperationDescriptor apply(OperationItem operationItem) { return (JvmTestOperationDescriptor) operationItem.getFinishEvent().getDescriptor(); } }).toList(); } private boolean isFailedJvmTest(OperationItem operationItem) { if (operationItem.getFinishEvent() instanceof TestFinishEvent) { TestFinishEvent testFinishEvent = (TestFinishEvent) operationItem.getFinishEvent(); if (testFinishEvent.getResult() instanceof TestFailureResult && testFinishEvent.getDescriptor() instanceof JvmTestOperationDescriptor) { JvmTestOperationDescriptor descriptor = (JvmTestOperationDescriptor) testFinishEvent.getDescriptor(); if (descriptor.getJvmTestKind() == JvmTestKind.ATOMIC || descriptor.getJvmTestKind() == JvmTestKind.UNKNOWN) { return true; } } } return false; } }