/* * Copyright 2000-2016 JetBrains s.r.o. * * 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 com.intellij.execution.impl; import com.intellij.execution.ExecutionManager; import com.intellij.execution.RunManagerConfig; import com.intellij.execution.RunnerAndConfigurationSettings; import com.intellij.execution.executors.DefaultRunExecutor; import com.intellij.execution.process.ProcessHandler; import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.runners.ExecutionEnvironmentBuilder; import com.intellij.execution.ui.RunContentDescriptor; import com.intellij.openapi.project.Project; import com.intellij.testFramework.LightPlatformTestCase; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; public class ExecutionManagerTest extends LightPlatformTestCase { private boolean myRestartRequiresConfirmation; @Override public void setUp() throws Exception { super.setUp(); RunManagerConfig config = RunManagerImpl.getInstanceImpl(getProject()).getConfig(); myRestartRequiresConfirmation = config.isRestartRequiresConfirmation(); config.setRestartRequiresConfirmation(false); } @Override public void tearDown() throws Exception { try { ExecutionTestUtil.terminateAllRunningDescriptors(ExecutionManager.getInstance(getProject())); RunManagerConfig config = RunManagerImpl.getInstanceImpl(getProject()).getConfig(); config.setRestartRequiresConfirmation(myRestartRequiresConfirmation); } finally { super.tearDown(); } } public void testRerunSingleton() throws Exception { Project project = getProject(); ExecutionManagerImpl executionManager = ExecutionManagerImpl.getInstance(project); FakeRunConfiguration rc = new FakeRunConfiguration(project, true); RunnerAndConfigurationSettingsImpl settings = new RunnerAndConfigurationSettingsImpl( RunManagerImpl.getInstanceImpl(project), rc, false ); settings.setSingleton(true); ExecutionEnvironment env1 = createEnv(project, settings); executionManager.restartRunProfile(env1); UIUtil.dispatchAllInvocationEvents(); ProcessHandler processHandler1 = getProcessHandler(executionManager); ExecutionEnvironment env2 = createEnv(project, settings); executionManager.restartRunProfile(env2); // Dispatching all events at this point will run into an endless cycle, because // runContentDescriptors of the same type are asked to terminate and then are awaited for termination: // com.intellij.execution.impl.ExecutionManagerImpl.awaitTermination // // However, the created processHandler is not willing to terminate on the first request (surviveSoftKill=true). // It will be terminated on the second request: executionManager.restartRunProfile(env3) ProcessHandler processHandler2 = getProcessHandler(executionManager); assertTrue(processHandler1 == processHandler2); assertTrue(processHandler1.isProcessTerminating()); ExecutionEnvironment env3 = createEnv(project, settings); executionManager.restartRunProfile(env3); UIUtil.dispatchAllInvocationEvents(); FakeProcessHandler processHandler3 = getProcessHandler(executionManager); assertTrue(processHandler1 != processHandler3); assertTrue(!processHandler3.isProcessTerminating() && !processHandler3.isProcessTerminated()); processHandler3.killProcess(); } @NotNull private static FakeProcessHandler getProcessHandler(@NotNull ExecutionManagerImpl executionManager) { RunContentDescriptor descriptor = ExecutionTestUtil.getSingleRunContentDescriptor(executionManager); ProcessHandler processHandler = descriptor.getProcessHandler(); assertNotNull(processHandler); return (FakeProcessHandler)processHandler; } @NotNull private static ExecutionEnvironment createEnv(@NotNull Project project, @NotNull RunnerAndConfigurationSettings settings) { return new ExecutionEnvironmentBuilder(project, DefaultRunExecutor.getRunExecutorInstance()) .runnerAndSettings(FakeProgramRunner.INSTANCE, settings) .build(); } }