]> source.dussan.org Git - sonarqube.git/blob
717e26d888f6eb142da31344e58070e3dadd260e
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2017 SonarSource SA
4  * mailto:info AT sonarsource DOT com
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 3 of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  */
20 package org.sonarqube.tests.qualityGate;
21
22 import com.sonar.orchestrator.Orchestrator;
23 import com.sonar.orchestrator.build.SonarScanner;
24 import java.io.File;
25 import java.io.IOException;
26 import java.io.StringReader;
27 import java.nio.charset.StandardCharsets;
28 import java.util.Properties;
29 import org.apache.commons.io.FileUtils;
30 import org.junit.ClassRule;
31 import org.junit.Rule;
32 import org.junit.Test;
33 import org.sonarqube.qa.util.Tester;
34 import org.sonarqube.ws.Ce;
35 import org.sonarqube.ws.MediaTypes;
36 import org.sonarqube.ws.Organizations;
37 import org.sonarqube.ws.Projects.CreateWsResponse.Project;
38 import org.sonarqube.ws.Qualitygates;
39 import org.sonarqube.ws.Users;
40 import org.sonarqube.ws.client.GetRequest;
41 import org.sonarqube.ws.client.WsResponse;
42 import org.sonarqube.ws.client.qualitygates.CreateConditionRequest;
43 import org.sonarqube.ws.client.qualitygates.ProjectStatusRequest;
44 import org.sonarqube.ws.client.qualitygates.UpdateConditionRequest;
45
46 import static org.assertj.core.api.Assertions.assertThat;
47 import static util.ItUtils.getMeasure;
48 import static util.ItUtils.projectDir;
49
50 public class OrganizationQualityGateForSmallChangesetsTest {
51
52   @ClassRule
53   public static Orchestrator orchestrator = OrganizationQualityGateSuite.ORCHESTRATOR;
54
55   @Rule
56   public Tester tester = new Tester(orchestrator);
57
58   @Test
59   public void do_not_fail_quality_gate_with_poor_LEAK_coverage_and_a_max_of_19_lines_of_NEW_code() throws Exception {
60     Organizations.Organization organization = tester.organizations().generate();
61     Project project = tester.projects().provision(organization);
62     Qualitygates.CreateResponse qualityGate = tester.qGates().generate(organization);
63     tester.qGates().associateProject(organization, qualityGate, project);
64     Qualitygates.CreateConditionResponse condition = tester.wsClient().qualitygates().createCondition(new CreateConditionRequest()
65       .setOrganization(organization.getKey())
66       .setGateId(String.valueOf(qualityGate.getId()))
67       .setMetric("new_coverage")
68       .setOp("LT")
69       .setWarning("90")
70       .setError("80")
71       .setPeriod("1"));
72
73     tester.settings().setProjectSetting(project.getKey(), "sonar.leak.period", "previous_version");
74     String password = "password1";
75     Users.CreateWsResponse.User user = tester.users().generateAdministrator(organization, u -> u.setPassword(password));
76
77     // no leak => use usual behaviour
78     SonarScanner analysis = SonarScanner
79       .create(projectDir("qualitygate/small-changesets/v1-1000-lines"))
80       .setProperty("sonar.projectKey", project.getKey())
81       .setProperty("sonar.organization", organization.getKey())
82       .setProperty("sonar.login", user.getLogin())
83       .setProperty("sonar.password", password)
84       .setProperty("sonar.scm.provider", "xoo")
85       .setProperty("sonar.scm.disabled", "false")
86       .setProperty("sonar.projectDate", "2013-04-01")
87       .setDebugLogs(true);
88     orchestrator.executeBuild(analysis);
89     assertThat(getMeasure(orchestrator, project.getKey(), "alert_status").getValue()).isEqualTo("OK");
90     assertIgnoredConditions(organization,"qualitygate/small-changesets/v1-1000-lines", false);
91
92     // small leak => ignore coverage warning or error
93     SonarScanner analysis2 = SonarScanner
94       .create(projectDir("qualitygate/small-changesets/v2-1019-lines"))
95       .setProperty("sonar.projectKey", project.getKey())
96       .setProperty("sonar.organization", organization.getKey())
97       .setProperty("sonar.login", user.getLogin())
98       .setProperty("sonar.password", password)
99       .setProperty("sonar.scm.provider", "xoo")
100       .setProperty("sonar.scm.disabled", "false")
101       .setProperty("sonar.projectDate", "2014-04-01")
102       .setDebugLogs(true);
103     orchestrator.executeBuild(analysis2);
104     assertThat(getMeasure(orchestrator, project.getKey(), "alert_status").getValue()).isEqualTo("OK");
105     assertIgnoredConditions(organization, "qualitygate/small-changesets/v2-1019-lines", true);
106
107     // small leak => if coverage is OK anyways, we do not have to ignore anything
108     tester.wsClient().qualitygates().updateCondition(new UpdateConditionRequest()
109       .setOrganization(organization.getKey())
110       .setId(String.valueOf(condition.getId()))
111       .setMetric("new_coverage")
112       .setOp("LT")
113       .setWarning("10")
114       .setError("20")
115       .setPeriod("1"));
116     SonarScanner analysis3 = SonarScanner
117       .create(projectDir("qualitygate/small-changesets/v2-1019-lines"))
118       .setProperty("sonar.projectKey", project.getKey())
119       .setProperty("sonar.organization", organization.getKey())
120       .setProperty("sonar.login", user.getLogin())
121       .setProperty("sonar.password", password)
122       .setProperty("sonar.scm.provider", "xoo")
123       .setProperty("sonar.scm.disabled", "false")
124       .setProperty("sonar.projectDate", "2014-04-02")
125       .setDebugLogs(true);
126     orchestrator.executeBuild(analysis3);
127     assertThat(getMeasure(orchestrator, project.getKey(), "alert_status").getValue()).isEqualTo("OK");
128     assertIgnoredConditions(organization, "qualitygate/small-changesets/v2-1019-lines", false);
129
130     // big leak => use usual behaviour
131     tester.wsClient().qualitygates().updateCondition(new UpdateConditionRequest()
132       .setOrganization(organization.getKey())
133       .setId(String.valueOf(condition.getId()))
134       .setMetric("new_coverage")
135       .setOp("LT")
136       .setWarning(null)
137       .setError("70")
138       .setPeriod("1"));
139     SonarScanner analysis4 = SonarScanner
140       .create(projectDir("qualitygate/small-changesets/v2-1020-lines"))
141       .setProperty("sonar.projectKey", project.getKey())
142       .setProperty("sonar.organization", organization.getKey())
143       .setProperty("sonar.login", user.getLogin())
144       .setProperty("sonar.password", password)
145       .setProperty("sonar.scm.provider", "xoo")
146       .setProperty("sonar.scm.disabled", "false")
147       .setProperty("sonar.projectDate", "2014-04-03")
148       .setDebugLogs(true);
149     orchestrator.executeBuild(analysis4);
150     assertThat(getMeasure(orchestrator, project.getKey(), "alert_status").getValue()).isEqualTo("ERROR");
151     assertIgnoredConditions(organization, "qualitygate/small-changesets/v2-1020-lines", false);
152   }
153
154   private void assertIgnoredConditions(Organizations.Organization organization, String projectDir, boolean expected) throws IOException {
155     String analysisId = getAnalysisId(getTaskIdInLocalReport(projectDir(projectDir)));
156     boolean ignoredConditions = tester.wsClient().qualitygates()
157       .projectStatus(new ProjectStatusRequest().setOrganization(organization.getKey()).setAnalysisId(analysisId))
158       .getProjectStatus()
159       .getIgnoredConditions();
160     assertThat(ignoredConditions).isEqualTo(expected);
161   }
162
163   private String getAnalysisId(String taskId) throws IOException {
164     WsResponse activity = tester.wsClient()
165       .wsConnector()
166       .call(new GetRequest("api/ce/task")
167         .setParam("id", taskId)
168         .setMediaType(MediaTypes.PROTOBUF));
169     Ce.TaskResponse activityWsResponse = Ce.TaskResponse.parseFrom(activity.contentStream());
170     return activityWsResponse.getTask().getAnalysisId();
171   }
172
173   private String getTaskIdInLocalReport(File projectDirectory) throws IOException {
174     File metadata = new File(projectDirectory, ".sonar/report-task.txt");
175     assertThat(metadata).exists().isFile();
176     // verify properties
177     Properties props = new Properties();
178     props.load(new StringReader(FileUtils.readFileToString(metadata, StandardCharsets.UTF_8)));
179     assertThat(props.getProperty("ceTaskId")).isNotEmpty();
180
181     return props.getProperty("ceTaskId");
182   }
183 }