]> source.dussan.org Git - sonarqube.git/blob
e4f9bf3fd273001ff9ba17f7c0bb8b866070a5a8
[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.MediaTypes;
35 import org.sonarqube.ws.Organizations;
36 import org.sonarqube.ws.Ce;
37 import org.sonarqube.ws.Projects.CreateWsResponse.Project;
38 import org.sonarqube.ws.Qualitygates;
39 import org.sonarqube.ws.Qualitygates.CreateWsResponse;
40 import org.sonarqube.ws.Users;
41 import org.sonarqube.ws.client.GetRequest;
42 import org.sonarqube.ws.client.WsResponse;
43 import org.sonarqube.ws.client.qualitygates.CreateConditionRequest;
44 import org.sonarqube.ws.client.qualitygates.ProjectStatusRequest;
45 import org.sonarqube.ws.client.qualitygates.UpdateConditionRequest;
46
47 import static org.assertj.core.api.Assertions.assertThat;
48 import static util.ItUtils.getMeasure;
49 import static util.ItUtils.projectDir;
50
51 public class OrganizationQualityGateForSmallChangesetsTest {
52
53   @ClassRule
54   public static Orchestrator orchestrator = OrganizationQualityGateSuite.ORCHESTRATOR;
55
56   @Rule
57   public Tester tester = new Tester(orchestrator);
58
59   @Test
60   public void do_not_fail_quality_gate_with_poor_LEAK_coverage_and_a_max_of_19_lines_of_NEW_code() throws Exception {
61     Organizations.Organization organization = tester.organizations().generate();
62     Project project = tester.projects().provision(organization);
63     CreateWsResponse qualityGate = tester.qGates().generate();
64     tester.qGates().associateProject(qualityGate, project);
65     Qualitygates.CreateConditionWsResponse condition = tester.wsClient().qualityGates().createCondition(new CreateConditionRequest()
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("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("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       .setId(String.valueOf(condition.getId()))
110       .setMetric("new_coverage")
111       .setOp("LT")
112       .setWarning("10")
113       .setError("20")
114       .setPeriod("1"));
115     SonarScanner analysis3 = SonarScanner
116       .create(projectDir("qualitygate/small-changesets/v2-1019-lines"))
117       .setProperty("sonar.projectKey", project.getKey())
118       .setProperty("sonar.organization", organization.getKey())
119       .setProperty("sonar.login", user.getLogin())
120       .setProperty("sonar.password", password)
121       .setProperty("sonar.scm.provider", "xoo")
122       .setProperty("sonar.scm.disabled", "false")
123       .setProperty("sonar.projectDate", "2014-04-02")
124       .setDebugLogs(true);
125     orchestrator.executeBuild(analysis3);
126     assertThat(getMeasure(orchestrator, project.getKey(), "alert_status").getValue()).isEqualTo("OK");
127     assertIgnoredConditions("qualitygate/small-changesets/v2-1019-lines", false);
128
129     // big leak => use usual behaviour
130     tester.wsClient().qualityGates().updateCondition(new UpdateConditionRequest()
131       .setId(String.valueOf(condition.getId()))
132       .setMetric("new_coverage")
133       .setOp("LT")
134       .setWarning(null)
135       .setError("70")
136       .setPeriod("1"));
137     SonarScanner analysis4 = SonarScanner
138       .create(projectDir("qualitygate/small-changesets/v2-1020-lines"))
139       .setProperty("sonar.projectKey", project.getKey())
140       .setProperty("sonar.organization", organization.getKey())
141       .setProperty("sonar.login", user.getLogin())
142       .setProperty("sonar.password", password)
143       .setProperty("sonar.scm.provider", "xoo")
144       .setProperty("sonar.scm.disabled", "false")
145       .setProperty("sonar.projectDate", "2014-04-03")
146       .setDebugLogs(true);
147     orchestrator.executeBuild(analysis4);
148     assertThat(getMeasure(orchestrator, project.getKey(), "alert_status").getValue()).isEqualTo("ERROR");
149     assertIgnoredConditions("qualitygate/small-changesets/v2-1020-lines", false);
150   }
151
152   private void assertIgnoredConditions(String projectDir, boolean expected) throws IOException {
153     String analysisId = getAnalysisId(getTaskIdInLocalReport(projectDir(projectDir)));
154     boolean ignoredConditions = tester.wsClient().qualityGates()
155       .projectStatus(new ProjectStatusRequest().setAnalysisId(analysisId))
156       .getProjectStatus()
157       .getIgnoredConditions();
158     assertThat(ignoredConditions).isEqualTo(expected);
159   }
160
161   private String getAnalysisId(String taskId) throws IOException {
162     WsResponse activity = tester.wsClient()
163       .wsConnector()
164       .call(new GetRequest("api/ce/task")
165         .setParam("id", taskId)
166         .setMediaType(MediaTypes.PROTOBUF));
167     Ce.TaskResponse activityWsResponse = Ce.TaskResponse.parseFrom(activity.contentStream());
168     return activityWsResponse.getTask().getAnalysisId();
169   }
170
171   private String getTaskIdInLocalReport(File projectDirectory) throws IOException {
172     File metadata = new File(projectDirectory, ".sonar/report-task.txt");
173     assertThat(metadata).exists().isFile();
174     // verify properties
175     Properties props = new Properties();
176     props.load(new StringReader(FileUtils.readFileToString(metadata, StandardCharsets.UTF_8)));
177     assertThat(props.getProperty("ceTaskId")).isNotEmpty();
178
179     return props.getProperty("ceTaskId");
180   }
181 }