/* * Copyright 2016 Nokia Solutions and Networks * Licensed under the Apache License, Version 2.0, * see license.txt file for details. */ package org.robotframework.ide.eclipse.main.plugin.launch.tabs; import static com.google.common.collect.Lists.newArrayList; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.debug.core.ILaunchConfiguration; import org.hamcrest.CoreMatchers; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.rf.ide.core.executor.RobotRuntimeEnvironment; import org.robotframework.ide.eclipse.main.plugin.launch.local.RobotLaunchConfiguration; import org.robotframework.ide.eclipse.main.plugin.launch.remote.RemoteRobotLaunchConfiguration; import org.robotframework.ide.eclipse.main.plugin.launch.tabs.LaunchConfigurationTabValidator.LaunchConfigurationValidationException; import org.robotframework.ide.eclipse.main.plugin.launch.tabs.LaunchConfigurationTabValidator.LaunchConfigurationValidationFatalException; import org.robotframework.ide.eclipse.main.plugin.mockmodel.RuntimeEnvironmentsMocks; import org.robotframework.ide.eclipse.main.plugin.model.RobotModel; import org.robotframework.ide.eclipse.main.plugin.model.RobotProject; import org.robotframework.red.junit.ProjectProvider; import org.robotframework.red.junit.RunConfigurationProvider; import com.google.common.collect.ImmutableMap; public class LaunchConfigurationTabValidatorTest { private static final String PROJECT_NAME = LaunchConfigurationTabValidatorTest.class.getSimpleName(); private final LaunchConfigurationTabValidator validator = new LaunchConfigurationTabValidator(); @Rule public final ExpectedException thrown = ExpectedException.none(); @Rule public ProjectProvider projectProvider = new ProjectProvider(PROJECT_NAME); @Rule public RunConfigurationProvider robotRunConfigurationProvider = new RunConfigurationProvider( RobotLaunchConfiguration.TYPE_ID); @Rule public RunConfigurationProvider remoteRobotRunConfigurationProvider = new RunConfigurationProvider( RemoteRobotLaunchConfiguration.TYPE_ID); @Test public void whenProjectNameIsEmpty_fatalExceptionIsThrown() throws Exception { thrown.expect(LaunchConfigurationValidationFatalException.class); thrown.expectMessage("Project cannot be empty"); validator.validateRobotTab(createRobotLaunchConfiguration("")); } @Test public void whenProjectDoesNotExist_fatalExceptionIsThrown() throws Exception { projectProvider.getProject().delete(true, null); thrown.expect(LaunchConfigurationValidationFatalException.class); thrown.expectMessage("Project '" + PROJECT_NAME + "' cannot be found in workspace"); validator.validateRobotTab(createRobotLaunchConfiguration(PROJECT_NAME)); } @Test public void whenProjectIsClosed_fatalExceptionIsThrown() throws Exception { thrown.expect(LaunchConfigurationValidationFatalException.class); thrown.expectMessage("Project '" + PROJECT_NAME + "' is currently closed"); projectProvider.getProject().close(null); validator.validateRobotTab(createRobotLaunchConfiguration(PROJECT_NAME)); } @Test public void whenThereAreNoSuitesSpecified_warningExceptionIsThrown() throws Exception { thrown.expect(LaunchConfigurationValidationException.class); thrown.expectMessage("There are no suites specified. All suites in '" + PROJECT_NAME + "' will be executed."); final RobotRuntimeEnvironment environment = RuntimeEnvironmentsMocks.createValidRobotEnvironment("RF 3.0"); final RobotProject robotProject = mock(RobotProject.class); final RobotModel model = mock(RobotModel.class); when(model.createRobotProject(projectProvider.getProject())).thenReturn(robotProject); when(robotProject.getRuntimeEnvironment()).thenReturn(environment); final LaunchConfigurationTabValidator validator = new LaunchConfigurationTabValidator(model); validator.validateRobotTab(createRobotLaunchConfiguration(PROJECT_NAME)); } @Test public void whenSuitesSpecifiedToRunDoesNotExist_fatalExceptionIsThrown() throws Exception, CoreException { thrown.expect(LaunchConfigurationValidationFatalException.class); thrown.expectMessage(CoreMatchers .<String> either(CoreMatchers.<String> equalTo("Following suites does not exist: /" + PROJECT_NAME + "/file2.robot, /" + PROJECT_NAME + "/suite/dir")) .or(CoreMatchers.<String> equalTo("Following suites does not exist: /" + PROJECT_NAME + "/suite/dir, /" + PROJECT_NAME + "/file2.robot"))); final IPath filePath = Path.fromPortableString("file.robot"); projectProvider.createFile(filePath, "*** Test Cases ***", "case1", " Log 10"); final RobotRuntimeEnvironment environment = RuntimeEnvironmentsMocks.createValidRobotEnvironment("RF 3.0"); final RobotProject robotProject = mock(RobotProject.class); final RobotModel model = mock(RobotModel.class); when(model.createRobotProject(projectProvider.getProject())).thenReturn(robotProject); when(robotProject.getRuntimeEnvironment()).thenReturn(environment); final LaunchConfigurationTabValidator validator = new LaunchConfigurationTabValidator(model); final RobotLaunchConfiguration launchConfig = createRobotLaunchConfiguration(PROJECT_NAME); launchConfig.setSuitePaths(ImmutableMap.of(filePath.toPortableString(), newArrayList(), "file2.robot", newArrayList(), "suite/dir", newArrayList())); validator.validateRobotTab(launchConfig); } @Test public void whenTestsSpecifiedInSuiteDoNotExist_fatalExceptionIsThrown() throws Exception, CoreException { thrown.expect(LaunchConfigurationValidationFatalException.class); thrown.expectMessage(CoreMatchers.equalTo("Following tests does not exist: case4, case5")); final IPath filePath = Path.fromPortableString("file.robot"); projectProvider.createFile(filePath, "*** Test Cases ***", "case1", " Log 10", "case2", " Log 20", "case3", " Log 30"); final RobotRuntimeEnvironment environment = RuntimeEnvironmentsMocks.createValidRobotEnvironment("RF 3.0"); final RobotProject robotProject = mock(RobotProject.class); final RobotModel model = mock(RobotModel.class); when(model.createRobotProject(projectProvider.getProject())).thenReturn(robotProject); when(robotProject.getRuntimeEnvironment()).thenReturn(environment); final LaunchConfigurationTabValidator validator = new LaunchConfigurationTabValidator(model); final RobotLaunchConfiguration launchConfig = createRobotLaunchConfiguration(PROJECT_NAME); launchConfig .setSuitePaths(ImmutableMap.of(filePath.toPortableString(), newArrayList("case3", "case4", "case5"))); validator.validateRobotTab(launchConfig); } @Test public void nothingIsThrown_whenEverythingIsOkWithRobotTab() throws Exception, CoreException { final IPath filePath = Path.fromPortableString("file.robot"); projectProvider.createFile(filePath, "*** Test Cases ***", "case1", " Log 10", "case2", " Log 20", "case3", " Log 30"); final RobotRuntimeEnvironment environment = RuntimeEnvironmentsMocks.createValidRobotEnvironment("RF 3.0"); final RobotProject robotProject = mock(RobotProject.class); final RobotModel model = mock(RobotModel.class); when(model.createRobotProject(projectProvider.getProject())).thenReturn(robotProject); when(robotProject.getRuntimeEnvironment()).thenReturn(environment); final LaunchConfigurationTabValidator validator = new LaunchConfigurationTabValidator(model); final RobotLaunchConfiguration launchConfig = createRobotLaunchConfiguration(PROJECT_NAME); launchConfig.setSuitePaths(ImmutableMap.of(filePath.toPortableString(), newArrayList("case2", "case3"))); validator.validateRobotTab(launchConfig); } @Test public void whenRemoteProjectNameIsEmpty_fatalExceptionIsThrown() throws Exception { thrown.expect(LaunchConfigurationValidationFatalException.class); thrown.expectMessage("Project cannot be empty"); validator.validateListenerTab(createRemoteRobotLaunchConfiguration("")); } @Test public void whenPortIsNotCorrect_fatalExceptionIsThrown() throws CoreException { thrown.expect(LaunchConfigurationValidationFatalException.class); thrown.expectMessage("Server port 'xyz' must be an Integer between 1 and 65,535"); final RemoteRobotLaunchConfiguration launchConfig = createRemoteRobotLaunchConfiguration(PROJECT_NAME); launchConfig.setAgentConnectionPortValue("xyz"); validator.validateListenerTab(launchConfig); } @Test public void whenTimeoutIsNotCorrect_fatalExceptionIsThrown() throws CoreException { thrown.expect(LaunchConfigurationValidationFatalException.class); thrown.expectMessage("Connection timeout 'xyz' must be an Integer between 1 and 3,600"); final RemoteRobotLaunchConfiguration launchConfig = createRemoteRobotLaunchConfiguration(PROJECT_NAME); launchConfig.setAgentConnectionTimeoutValue("xyz"); validator.validateListenerTab(launchConfig); } @Test public void nothingIsThrown_whenEverythingIsOkWithListenerTab() throws Exception { validator.validateListenerTab(createRemoteRobotLaunchConfiguration(PROJECT_NAME)); } @Test public void nothingIsThrown_whenEverythingIsOkWithListenerTab_1() throws Exception { final RobotLaunchConfiguration launchConfig = createRobotLaunchConfiguration(PROJECT_NAME); launchConfig.setUsingRemoteAgent(true); launchConfig.setAgentConnectionHostValue("1.2.3.4"); launchConfig.setAgentConnectionPortValue("12345"); launchConfig.setAgentConnectionTimeoutValue("99"); validator.validateListenerTab(launchConfig); } @Test public void projectIsNotValidated_whenNotDefinedDirectly() throws Exception { validator.validateListenerTab(createRobotLaunchConfiguration("")); } @Test public void whenSystemInterpreterIsUsed_warningExceptionIsThrown() throws Exception { thrown.expect(LaunchConfigurationValidationException.class); thrown.expectMessage(CoreMatchers .equalTo("Tests will be launched using 'Python' interpreter as defined in PATH environment variable")); final IPath filePath = Path.fromPortableString("file.robot"); projectProvider.createFile(filePath, "*** Test Cases ***", "case1", " Log 10"); final LaunchConfigurationTabValidator validator = new LaunchConfigurationTabValidator(); final RobotLaunchConfiguration launchConfig = createRobotLaunchConfiguration(PROJECT_NAME); launchConfig.setUsingInterpreterFromProject(false); launchConfig.setSuitePaths(ImmutableMap.of(filePath.toPortableString(), newArrayList())); validator.validateExecutorTab(launchConfig); } @Test public void whenExecutableFileDoesNotExist_fatalExceptionIsThrown() throws CoreException { thrown.expect(LaunchConfigurationValidationFatalException.class); thrown.expectMessage("Executable file does not exist"); final RobotLaunchConfiguration launchConfig = createRobotLaunchConfiguration(PROJECT_NAME); launchConfig.setExecutableFilePath("/not/existing/path"); validator.validateExecutorTab(launchConfig); } @Test public void whenProjectIsUsingInvalidEnvironment_fatalExceptionIsThrown_1() throws Exception { thrown.expect(LaunchConfigurationValidationFatalException.class); thrown.expectMessage("Project '" + PROJECT_NAME + "' is using invalid Python environment"); final RobotProject robotProject = mock(RobotProject.class); final RobotModel model = mock(RobotModel.class); when(model.createRobotProject(projectProvider.getProject())).thenReturn(robotProject); when(robotProject.getRuntimeEnvironment()).thenReturn(null); final LaunchConfigurationTabValidator validator = new LaunchConfigurationTabValidator(model); validator.validateExecutorTab(createRobotLaunchConfiguration(PROJECT_NAME)); } @Test public void whenProjectIsUsingInvalidEnvironment_fatalExceptionIsThrown_2() throws Exception { thrown.expect(LaunchConfigurationValidationFatalException.class); thrown.expectMessage("Project '" + PROJECT_NAME + "' is using invalid Python environment"); final RobotRuntimeEnvironment environment = RuntimeEnvironmentsMocks.createInvalidPythonEnvironment(); final RobotProject robotProject = mock(RobotProject.class); final RobotModel model = mock(RobotModel.class); when(model.createRobotProject(projectProvider.getProject())).thenReturn(robotProject); when(robotProject.getRuntimeEnvironment()).thenReturn(environment); final LaunchConfigurationTabValidator validator = new LaunchConfigurationTabValidator(model); validator.validateExecutorTab(createRobotLaunchConfiguration(PROJECT_NAME)); } @Test public void whenProjectIsUsingInvalidEnvironment_fatalExceptionIsThrown_3() throws Exception { thrown.expect(LaunchConfigurationValidationFatalException.class); thrown.expectMessage( "Project '" + PROJECT_NAME + "' is using invalid Python environment (missing Robot Framework)"); final RobotRuntimeEnvironment environment = RuntimeEnvironmentsMocks.createInvalidRobotEnvironment(); final RobotProject robotProject = mock(RobotProject.class); final RobotModel model = mock(RobotModel.class); when(model.createRobotProject(projectProvider.getProject())).thenReturn(robotProject); when(robotProject.getRuntimeEnvironment()).thenReturn(environment); final LaunchConfigurationTabValidator validator = new LaunchConfigurationTabValidator(model); validator.validateExecutorTab(createRobotLaunchConfiguration(PROJECT_NAME)); } @Test public void nothingIsThrown_whenEverythingIsOkWithExecutorTab() throws Exception { final IFile executableFile = projectProvider.createFile("robot_executable_file.txt", "run robot command"); final IFile testFile = projectProvider.createFile("test.robot", "*** Test Cases ***", "case1", " Log 1"); final RobotLaunchConfiguration launchConfig = createRobotLaunchConfiguration(PROJECT_NAME); launchConfig.setExecutableFilePath(executableFile.getLocation().toOSString()); launchConfig.setSuitePaths(ImmutableMap.of(testFile.getName(), newArrayList("case1"))); validator.validateExecutorTab(launchConfig); } private RobotLaunchConfiguration createRobotLaunchConfiguration(final String projectName) throws CoreException { final ILaunchConfiguration configuration = robotRunConfigurationProvider.create("robot"); final RobotLaunchConfiguration launchConfig = new RobotLaunchConfiguration(configuration); launchConfig.fillDefaults(); launchConfig.setProjectName(projectName); return launchConfig; } private RemoteRobotLaunchConfiguration createRemoteRobotLaunchConfiguration(final String projectName) throws CoreException { final ILaunchConfiguration configuration = remoteRobotRunConfigurationProvider.create("remote"); final RemoteRobotLaunchConfiguration launchConfig = new RemoteRobotLaunchConfiguration(configuration); launchConfig.fillDefaults(); launchConfig.setProjectName(projectName); return launchConfig; } }