/*
* 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.project.build.validation;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.io.File;
import java.io.IOException;
import java.net.ServerSocket;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.rf.ide.core.project.RobotProjectConfig;
import org.rf.ide.core.project.RobotProjectConfig.ReferencedVariableFile;
import org.rf.ide.core.project.RobotProjectConfig.RemoteLocation;
import org.rf.ide.core.project.RobotProjectConfig.SearchPath;
import org.rf.ide.core.project.RobotProjectConfigReader.RobotProjectConfigWithLines;
import org.rf.ide.core.validation.ProblemPosition;
import org.robotframework.ide.eclipse.main.plugin.model.RobotModel;
import org.robotframework.ide.eclipse.main.plugin.project.build.causes.ConfigFileProblem;
import org.robotframework.ide.eclipse.main.plugin.project.build.validation.MockReporter.Problem;
import org.robotframework.red.junit.ProjectProvider;
public class RobotProjectConfigFileValidatorTest {
private static final String PROJECT_NAME = RobotProjectConfigFileValidatorTest.class.getSimpleName();
@Rule
public ProjectProvider projectProvider = new ProjectProvider(PROJECT_NAME);
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
private RobotProjectConfigFileValidator validator;
private MockReporter reporter;
@Before
public void beforeTest() throws Exception {
reporter = new MockReporter();
final ValidationContext context = mock(ValidationContext.class);
when(context.getModel()).thenReturn(new RobotModel());
final IFile file = mock(IFile.class);
when(file.getProject()).thenReturn(projectProvider.getProject());
validator = new RobotProjectConfigFileValidator(context, file, reporter);
}
@Test
public void whenConfigIsNewlyCreated_itHasNoValidationIssues() throws Exception {
final RobotProjectConfig config = new RobotProjectConfig();
final Map<Object, ProblemPosition> locations = new HashMap<>();
final RobotProjectConfigWithLines linesAugmentedConfig = new RobotProjectConfigWithLines(config, locations);
validator.validate(new NullProgressMonitor(), linesAugmentedConfig);
assertThat(reporter.getReportedProblems()).isEmpty();
}
@Test
public void whenRemoteLocationHostDoesNotExist_unreachableHostProblemIsReported() throws Exception {
// opens the socket in order to find port, but the socket gets closed immediately
final RemoteLocation remoteLocation = RemoteLocation.create("http://127.0.0.1:" + findFreePort() + "/");
final RobotProjectConfig config = new RobotProjectConfig();
config.addRemoteLocation(remoteLocation);
final Map<Object, ProblemPosition> locations = new HashMap<>();
locations.put(remoteLocation, new ProblemPosition(42));
final RobotProjectConfigWithLines linesAugmentedConfig = new RobotProjectConfigWithLines(config, locations);
validator.validate(new NullProgressMonitor(), linesAugmentedConfig);
assertThat(reporter.getReportedProblems())
.containsExactly(new Problem(ConfigFileProblem.UNREACHABLE_HOST, new ProblemPosition(42)));
}
@Test
public void whenRemoteLocationHostDoesExist_nothingIsReported() throws Exception {
// opens the socket in order to find port, but the socket remains open till the test end, so
// no validation error is expected
try (ServerSocket socket = new ServerSocket(0)) {
final RemoteLocation remoteLocation = RemoteLocation
.create("http://127.0.0.1:" + socket.getLocalPort() + "/");
final RobotProjectConfig config = new RobotProjectConfig();
config.addRemoteLocation(remoteLocation);
final Map<Object, ProblemPosition> locations = new HashMap<>();
locations.put(remoteLocation, new ProblemPosition(42));
final RobotProjectConfigWithLines linesAugmentedConfig = new RobotProjectConfigWithLines(config, locations);
validator.validate(new NullProgressMonitor(), linesAugmentedConfig);
assertThat(reporter.getReportedProblems()).isEmpty();
} finally {
// nothing to do, just let the socket close itself
}
}
@Test
public void whenAbsoluteSearchPathExist_nothingIsReported() throws Exception {
final File folder = temporaryFolder.newFolder();
final SearchPath searchPath = SearchPath.create(folder.getAbsolutePath());
final RobotProjectConfig config = new RobotProjectConfig();
config.addClassPath(searchPath);
final Map<Object, ProblemPosition> locations = new HashMap<>();
locations.put(searchPath, new ProblemPosition(42));
final RobotProjectConfigWithLines linesAugmentedConfig = new RobotProjectConfigWithLines(config, locations);
validator.validate(new NullProgressMonitor(), linesAugmentedConfig);
assertThat(reporter.getReportedProblems()).isEmpty();
}
@Test
public void whenAbsoluteSearchPathDoesNotExist_missingLocationProblemIsReported() throws Exception {
final File folder = temporaryFolder.newFolder();
final String path = folder.getAbsolutePath();
folder.delete();
final SearchPath searchPath = SearchPath.create(path);
final RobotProjectConfig config = new RobotProjectConfig();
config.addClassPath(searchPath);
final Map<Object, ProblemPosition> locations = new HashMap<>();
locations.put(searchPath, new ProblemPosition(42));
final RobotProjectConfigWithLines linesAugmentedConfig = new RobotProjectConfigWithLines(config, locations);
validator.validate(new NullProgressMonitor(), linesAugmentedConfig);
assertThat(reporter.getReportedProblems())
.containsExactly(new Problem(ConfigFileProblem.MISSING_SEARCH_PATH, new ProblemPosition(42)));
}
@Test
public void whenRelativePathExist_nothingIsReported() throws Exception {
projectProvider.createDir(Path.fromPortableString("folder"));
final SearchPath searchPath = SearchPath.create(PROJECT_NAME + "/folder");
final RobotProjectConfig config = new RobotProjectConfig();
config.addPythonPath(searchPath);
final Map<Object, ProblemPosition> locations = new HashMap<>();
locations.put(searchPath, new ProblemPosition(42));
final RobotProjectConfigWithLines linesAugmentedConfig = new RobotProjectConfigWithLines(config, locations);
validator.validate(new NullProgressMonitor(), linesAugmentedConfig);
assertThat(reporter.getReportedProblems()).isEmpty();
}
@Test
public void whenRelativePathDoesNotExist_missingLocationProblemIsReported() throws Exception {
final SearchPath searchPath = SearchPath.create(PROJECT_NAME + "/folder");
final RobotProjectConfig config = new RobotProjectConfig();
config.addPythonPath(searchPath);
final Map<Object, ProblemPosition> locations = new HashMap<>();
locations.put(searchPath, new ProblemPosition(42));
final RobotProjectConfigWithLines linesAugmentedConfig = new RobotProjectConfigWithLines(config, locations);
validator.validate(new NullProgressMonitor(), linesAugmentedConfig);
assertThat(reporter.getReportedProblems())
.containsExactly(new Problem(ConfigFileProblem.MISSING_SEARCH_PATH, new ProblemPosition(42)));
}
@Test
public void whenVariableFileExist_nothingIsReported() throws Exception {
projectProvider.createDir(Path.fromPortableString("a"));
projectProvider.createFile(Path.fromPortableString("a/vars.py"), "VAR = 100");
final ReferencedVariableFile variableFile = ReferencedVariableFile.create(PROJECT_NAME + "/a/vars.py");
final RobotProjectConfig config = new RobotProjectConfig();
config.addReferencedVariableFile(variableFile);
final Map<Object, ProblemPosition> locations = new HashMap<>();
locations.put(variableFile, new ProblemPosition(42));
final RobotProjectConfigWithLines linesAugmentedConfig = new RobotProjectConfigWithLines(config, locations);
validator.validate(new NullProgressMonitor(), linesAugmentedConfig);
assertThat(reporter.getReportedProblems()).isEmpty();
}
@Test
public void whenVariableFileDoesntExist_missingFileIsReported() throws Exception {
projectProvider.createDir(Path.fromPortableString("a"));
projectProvider.createFile(Path.fromPortableString("a/vars2.py"), "VAR = 100");
final ReferencedVariableFile variableFile = ReferencedVariableFile.create(PROJECT_NAME + "a/vars.py");
final RobotProjectConfig config = new RobotProjectConfig();
config.addReferencedVariableFile(variableFile);
final Map<Object, ProblemPosition> locations = new HashMap<>();
locations.put(variableFile, new ProblemPosition(42));
final RobotProjectConfigWithLines linesAugmentedConfig = new RobotProjectConfigWithLines(config, locations);
validator.validate(new NullProgressMonitor(), linesAugmentedConfig);
assertThat(reporter.getReportedProblems())
.containsExactly(new Problem(ConfigFileProblem.MISSING_VARIABLE_FILE, new ProblemPosition(42)));
}
@Test
public void whenVariableFileExistAndIRelatedWithAbsolutePath_absolutePathWarningIsReported() throws Exception {
projectProvider.createDir(Path.fromPortableString("a"));
projectProvider.createFile(Path.fromPortableString("a/vars.py"), "VAR = 100");
final ReferencedVariableFile variableFile = ReferencedVariableFile
.create(projectProvider.getProject().getLocation() + "/a/vars.py");
final RobotProjectConfig config = new RobotProjectConfig();
config.addReferencedVariableFile(variableFile);
final Map<Object, ProblemPosition> locations = new HashMap<>();
locations.put(variableFile, new ProblemPosition(42));
final RobotProjectConfigWithLines linesAugmentedConfig = new RobotProjectConfigWithLines(config, locations);
validator.validate(new NullProgressMonitor(), linesAugmentedConfig);
assertThat(reporter.getReportedProblems())
.containsExactly(new Problem(ConfigFileProblem.ABSOLUTE_PATH, new ProblemPosition(42)));
}
@Test
public void whenVariableFileDoesntExistAndIsRelatedWithAbsolutePath_missingFileAndAbsolutePathWarningAreReported()
throws Exception {
projectProvider.createDir(Path.fromPortableString("a"));
projectProvider.createFile(Path.fromPortableString("a/vars2.py"), "VAR = 100");
final ReferencedVariableFile variableFile = ReferencedVariableFile
.create(projectProvider.getProject().getLocation() + "/a/vars.py");
final RobotProjectConfig config = new RobotProjectConfig();
config.addReferencedVariableFile(variableFile);
final Map<Object, ProblemPosition> locations = new HashMap<>();
locations.put(variableFile, new ProblemPosition(42));
final RobotProjectConfigWithLines linesAugmentedConfig = new RobotProjectConfigWithLines(config, locations);
validator.validate(new NullProgressMonitor(), linesAugmentedConfig);
assertThat(reporter.getReportedProblems()).containsOnly(
new Problem(ConfigFileProblem.MISSING_VARIABLE_FILE, new ProblemPosition(42)),
new Problem(ConfigFileProblem.ABSOLUTE_PATH, new ProblemPosition(42)));
}
@Test
public void whenValidationExcludedPathDoesNotExistInProject_warningIsReported() throws Exception {
projectProvider.createDir(Path.fromPortableString("directory"));
final RobotProjectConfig config = new RobotProjectConfig();
config.addExcludedPath("does/not/exist");
final Map<Object, ProblemPosition> locations = new HashMap<>();
locations.put(config.getExcludedPath().get(0), new ProblemPosition(42));
final RobotProjectConfigWithLines linesAugmentedConfig = new RobotProjectConfigWithLines(config, locations);
validator.validate(new NullProgressMonitor(), linesAugmentedConfig);
assertThat(reporter.getReportedProblems())
.containsExactly(new Problem(ConfigFileProblem.MISSING_EXCLUDED_FOLDER, new ProblemPosition(42)));
}
@Test
public void whenValidationExcludedPathExistInProject_nothingIsReported() throws Exception {
projectProvider.createDir(Path.fromPortableString("directory"));
final RobotProjectConfig config = new RobotProjectConfig();
config.addExcludedPath("directory");
final Map<Object, ProblemPosition> locations = new HashMap<>();
locations.put(config.getExcludedPath().get(0), new ProblemPosition(42));
final RobotProjectConfigWithLines linesAugmentedConfig = new RobotProjectConfigWithLines(config, locations);
validator.validate(new NullProgressMonitor(), linesAugmentedConfig);
assertThat(reporter.getReportedProblems()).isEmpty();
}
@Test
public void whenValidationExcludedPathExcludesAnotherPath_warningIsReported() throws Exception {
projectProvider.createDir(Path.fromPortableString("directory"));
projectProvider.createDir(Path.fromPortableString("directory/nested"));
projectProvider.createDir(Path.fromPortableString("directory/nested/1"));
projectProvider.createDir(Path.fromPortableString("directory/nested/1/2"));
projectProvider.createDir(Path.fromPortableString("directory/nested/1/2/3"));
final RobotProjectConfig config = new RobotProjectConfig();
config.addExcludedPath("directory/nested");
config.addExcludedPath("directory/nested/1/2");
final Map<Object, ProblemPosition> locations = new HashMap<>();
locations.put(config.getExcludedPath().get(0), new ProblemPosition(42));
locations.put(config.getExcludedPath().get(1), new ProblemPosition(43));
final RobotProjectConfigWithLines linesAugmentedConfig = new RobotProjectConfigWithLines(config, locations);
validator.validate(new NullProgressMonitor(), linesAugmentedConfig);
assertThat(reporter.getReportedProblems())
.containsExactly(new Problem(ConfigFileProblem.USELESS_FOLDER_EXCLUSION, new ProblemPosition(43)));
}
private static int findFreePort() {
try (ServerSocket socket = new ServerSocket(0)) {
return socket.getLocalPort();
} catch (final IOException e) {
throw new IllegalStateException();
}
}
}