/* * SonarQube * Copyright (C) 2009-2017 SonarSource SA * mailto:info AT sonarsource DOT com * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package it.plugins.checks; import com.google.common.base.Joiner; import com.google.gson.Gson; import com.sonar.orchestrator.Orchestrator; import it.plugins.Project; import java.io.File; import java.util.List; import java.util.Map; import org.hamcrest.Matchers; import org.junit.rules.ErrorCollector; import org.sonarqube.ws.client.GetRequest; import org.sonarqube.ws.client.WsResponse; import static java.util.Arrays.asList; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import static util.ItUtils.getMeasuresAsDoubleByMetricKey; import static util.ItUtils.newAdminWsClient; /** * * TODO must have syntax highlighting * TODO must have duplications * TODO must have issues with debt * TODO must have tests * TODO must have coverage */ public class Validation { private final Orchestrator orchestrator; private final ErrorCollector errorCollector; public Validation(Orchestrator orchestrator, ErrorCollector errorCollector) { this.orchestrator = orchestrator; this.errorCollector = errorCollector; } public void mustHaveIssues(String path) { // TODO use the WS api/issues mustHaveMeasuresGreaterThan(path, 1, "violations"); } public void mustHaveComments(String path) { mustHaveMeasuresGreaterThan(path, 0, "comment_lines", "comment_lines_density"); } public void mustHaveComplexity(String path) { mustHaveMeasuresGreaterThan(path, 0, "complexity"); } public void mustHaveSize(String path) { mustHaveMeasuresGreaterThan(path, 0, "ncloc", "lines"); } public void mustHaveMeasuresGreaterThan(String path, int min, String... metricKeys) { for (String filePath : toFiles(path)) { fileMustHaveMeasures(filePath, metricKeys, min); } } private void fileMustHaveMeasures(String filePath, String[] metricKeys, int min) { String componentKey = filePathToKey(filePath); Map<String, Double> measures = getMeasuresAsDoubleByMetricKey(orchestrator, componentKey, metricKeys); errorCollector.checkThat("Measures " + Joiner.on(",").join(metricKeys) + " are set on file " + filePath, componentKey, notNullValue()); if (!measures.isEmpty()) { for (String metricKey : metricKeys) { Double measure = measures.get(metricKey); errorCollector.checkThat("Measure " + metricKey + " is set on file " + filePath, measure, notNullValue()); if (measure != null) { errorCollector.checkThat("Measure " + metricKey + " is positive on file " + filePath, measure.intValue(), Matchers.greaterThanOrEqualTo(min)); } } } } /** * Checks that each source file of the given directory is uploaded to server. * @param path relative path to source directory or source file */ public void mustHaveNonEmptySource(String path) { mustHaveSourceWithAtLeast(path, 1); } public void mustHaveSource(String path) { mustHaveSourceWithAtLeast(path, 0); } private void mustHaveSourceWithAtLeast(String path, int minLines) { for (String filePath : toFiles(path)) { WsResponse response = newAdminWsClient(orchestrator).wsConnector().call(new GetRequest("api/sources/lines").setParam("key", filePathToKey(filePath))); errorCollector.checkThat("Source is set on file " + filePath, response.isSuccessful(), is(true)); Sources source = Sources.parse(response.content()); if (source != null) { errorCollector.checkThat("Source is empty on file " + filePath, source.getSources().size(), Matchers.greaterThanOrEqualTo(minLines)); } } } private Iterable<String> toFiles(String path) { File fileOrDir = new File(Project.basedir(), path); if (!fileOrDir.exists()) { throw new IllegalArgumentException("Path does not exist: " + fileOrDir); } if (fileOrDir.isDirectory()) { return Project.allFilesInDir(path); } return asList(path); } private String filePathToKey(String filePath) { return "all-langs:" + filePath; } public static class Sources { private List<Source> sources; private Sources(List<Source> sources) { this.sources = sources; } public List<Source> getSources() { return sources; } public static Sources parse(String json) { Gson gson = new Gson(); return gson.fromJson(json, Sources.class); } public static class Source { private final String line; private Source(String line) { this.line = line; } public String getLine() { return line; } } } }