package hudson.plugins.analysis.core;
import java.io.IOException;
import java.util.List;
import org.junit.Test;
import com.google.common.collect.Lists;
import static org.junit.Assert.*;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.*;
import hudson.plugins.analysis.core.ParserResult.Workspace;
import hudson.plugins.analysis.util.model.FileAnnotation;
import hudson.plugins.analysis.util.model.Priority;
/**
* Tests the class {@link ParserResult}.
*
* @author Ulli Hafner
*/
public class ParserResultTest {
private static final String OTHER_SCANNED_FILE = "other/file.txt";
private static final String SCANNED_FILENAME = "relative/path/to/file.txt";
private static final String SCANNED_FILENAME_WINDOWS = "relative\\path\\to\\file.txt";
private static final String WORSPACE_ROOT = "ws";
private static final String FOUND_FILE_NAME = WORSPACE_ROOT + "/" + SCANNED_FILENAME;
/**
* Verifies that the relative prefix of a path is stripped.
*/
@Test
public void shouldStripRelativePathPrefix() {
ParserResult parserResult = new ParserResult();
verifyPrefix(parserResult, "file.txt");
verifyPrefix(parserResult, "../file.txt");
verifyPrefix(parserResult, "../../file.txt");
verifyPrefix(parserResult, "../../../file.txt");
verifyPrefix(parserResult, "./../file.txt");
verifyPrefix(parserResult, "../bla/../file.txt");
assertEquals("Wrong prefix removal: ", "fi/file.txt", parserResult.stripRelativePrefix("fi/file.txt"));
}
private void verifyPrefix(final ParserResult parserResult, final String fileName) {
assertEquals("Wrong prefix removal: ", "file.txt", parserResult.stripRelativePrefix(fileName));
}
/**
* Verifies that the workspace scanning of files works with relative paths that contain references
* to parent directories.
*
* @see <a href="http://issues.jenkins-ci.org/browse/JENKINS-32150">Issue 32150</a>
*/
@Test
public void issue32150() throws Exception {
String[] workspaceFiles = {"directory-a/multi-file-in-subdir.txt",
"directory-b/multi-file-in-subdir.txt",
"directory-b/subdir/file2",
"file.txt",
"directory-a/subdir/file1",
"directory-a/file-in-subdir.txt",
"compile-log.txt"};
ParserResult result = createParserResult(workspaceFiles);
verifyWarningPath(result, "file.txt", "file.txt");
verifyWarningPath(result, "file-in-subdir.txt", "directory-a/file-in-subdir.txt");
verifyNoWarningPath(result, "multi-file-in-subdir.txt");
verifyWarningPath(result, "../file.txt", "file.txt");
verifyWarningPath(result, "../file-in-subdir.txt", "directory-a/file-in-subdir.txt");
verifyNoWarningPath(result, "../multi-file-in-subdir.txt");
verifyWarningPath(result, "../directory-a/../directory-a/../directory-a/file-in-subdir.txt", "directory-a/file-in-subdir.txt");
verifyWarningPath(result, "directory-a/../directory-a/../directory-a/file-in-subdir.txt", "directory-a/file-in-subdir.txt");
}
private void verifyNoWarningPath(final ParserResult result, final String fileName) {
FileAnnotation warning = mockWarning(fileName);
result.addAnnotation(warning);
verify(warning, never()).setFileName(anyString());
}
private void verifyWarningPath(final ParserResult result, final String fileName, final String workspacePath) {
verifyWarning(result, fileName, WORSPACE_ROOT + "/" + workspacePath);
}
private void verifyWarning(final ParserResult result, final String fileName, final String foundFileName) {
FileAnnotation warning = mockWarning(fileName);
result.addAnnotation(warning);
verify(warning).setFileName(foundFileName);
}
/**
* Verifies that the number of annotations is correctly returned.
*
* @throws Exception
* in case of an error
*/
@Test
public void testCountingOfAddAnnotation() {
ParserResult result = new ParserResult();
FileAnnotation warning = mockWarning("file.txt");
assertEquals("Warning correctly added.", 1, result.addAnnotation(warning));
assertEquals("Warning correctly not added.", 0, result.addAnnotation(warning));
}
/**
* Verifies that the number of annotations is correctly returned.
*
* @throws Exception
* in case of an error
*/
@Test
public void testCountingOfAddAnnotations() {
ParserResult result = new ParserResult();
List<FileAnnotation> warnings = Lists.newArrayList();
warnings.add(mockWarning("1"));
warnings.add(mockWarning("2"));
assertEquals("Warnings correctly added.", 2, result.addAnnotations(warnings));
assertEquals("Warnings correctly not added.", 0, result.addAnnotations(warnings));
}
/**
* Verifies that a simple file without path is correctly mapped.
*
* @throws Exception
* in case of an error
*/
@Test
public void testSimpleFileNameMapping() throws Exception {
String[] workspaceFiles = {SCANNED_FILENAME};
ParserResult result = createParserResult(workspaceFiles);
verifyWarning(result, "file.txt", FOUND_FILE_NAME);
}
/**
* Verifies that a file with path prefix is correctly mapped.
*
* @throws Exception
* in case of an error
*/
@Test
public void testFileNameMappingWithPrefix() throws Exception {
String[] workspaceFiles = {SCANNED_FILENAME};
ParserResult result = createParserResult(workspaceFiles);
verifyWarning(result, "to/file.txt", FOUND_FILE_NAME);
}
/**
* Verifies that a file (in Windows format) with path prefix is correctly mapped.
*
* @throws Exception
* in case of an error
*/
@Test
public void testWindowsFileNameMappingWithPrefix() throws Exception {
String[] workspaceFiles = {SCANNED_FILENAME_WINDOWS};
ParserResult result = createParserResult(workspaceFiles);
verifyWarning(result, "to/file.txt", FOUND_FILE_NAME);
}
/**
* Verifies that no file is mapped if the workspace contains duplicates and
* the warning could not be assigned.
*
* @throws Exception
* in case of an error
*/
@Test
public void testDuplicate() throws Exception {
String[] workspaceFiles = {SCANNED_FILENAME, OTHER_SCANNED_FILE};
ParserResult result = createParserResult(workspaceFiles);
FileAnnotation warning = mockWarning("file.txt");
result.addAnnotation(warning);
verify(warning, never()).setFileName(anyString());
}
private ParserResult createParserResult(String[] workspaceFiles) throws IOException, InterruptedException {
return new ParserResult(mockWorkspace(workspaceFiles), true);
}
/**
* Verifies that the file is mapped if the workspace contains duplicates and
* the warning could be assigned because the prefix is unique.
*
* @throws Exception
* in case of an error
*/
@Test
public void testUniquePrefixDuplicate() throws Exception {
ParserResult result = createParserResult(new String[] {SCANNED_FILENAME, OTHER_SCANNED_FILE});
verifyWarning(result, "path/to/file.txt", FOUND_FILE_NAME);
}
private FileAnnotation mockWarning(final String fileName) {
FileAnnotation warning = mock(FileAnnotation.class);
when(warning.getFileName()).thenReturn(fileName);
when(warning.getPriority()).thenReturn(Priority.HIGH);
return warning;
}
private Workspace mockWorkspace(final String[] workspaceFiles) throws IOException, InterruptedException {
Workspace workspace = mock(Workspace.class);
when(workspace.child(anyString())).thenReturn(workspace);
when(workspace.getPath()).thenReturn(WORSPACE_ROOT);
when(workspace.findFiles(anyString())).thenReturn(workspaceFiles);
return workspace;
}
}