]> source.dussan.org Git - sonarqube.git/blob
fd8d71284c046f2a52555c58428e36de0297d34c
[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();
63     tester.qGates().associateProject(qualityGate, project);
64     Qualitygates.CreateConditionResponse condition = tester.wsClient().qualityGates().createCondition(new CreateConditionRequest()
65       .setGateId(String.valueOf(qualityGate.getId()))
66       .setMetric("new_coverage")
67       .setOp("LT")
68       .setWarning("90")
69       .setError("80")
70       .setPeriod("1"));
71
72     tester.settings().setProjectSetting(project.getKey(), "sonar.leak.period", "previous_version");
73     String password = "password1";
74     Users.CreateWsResponse.User user = tester.users().generateAdministrator(organization, u -> u.setPassword(password));
75
76     // no leak => use usual behaviour
77     SonarScanner analysis = SonarScanner
78       .create(projectDir("qualitygate/small-changesets/v1-1000-lines"))
79       .setProperty("sonar.projectKey", project.getKey())
80       .setProperty("sonar.organization", organization.getKey())
81       .setProperty("sonar.login", user.getLogin())
82       .setProperty("sonar.password", password)
83       .setProperty("sonar.scm.provider", "xoo")
84       .setProperty("sonar.scm.disabled", "false")
85       .setProperty("sonar.projectDate", "2013-04-01")
86       .setDebugLogs(true);
87     orchestrator.executeBuild(analysis);
88     assertThat(getMeasure(orchestrator, project.getKey(), "alert_status").getValue()).isEqualTo("OK");
89     assertIgnoredConditions("qualitygate/small-changesets/v1-1000-lines", false);
90
91     // small leak => ignore coverage warning or error
92     SonarScanner analysis2 = SonarScanner
93       .create(projectDir("qualitygate/small-changesets/v2-1019-lines"))
94       .setProperty("sonar.projectKey", project.getKey())
95       .setProperty("sonar.organization", organization.getKey())
96       .setProperty("sonar.login", user.getLogin())
97       .setProperty("sonar.password", password)
98       .setProperty("sonar.scm.provider", "xoo")
99       .setProperty("sonar.scm.disabled", "false")
100       .setProperty("sonar.projectDate", "2014-04-01")
101       .setDebugLogs(true);
102     orchestrator.executeBuild(analysis2);
103     assertThat(getMeasure(orchestrator, project.getKey(), "alert_status").getValue()).isEqualTo("OK");
104     assertIgnoredConditions("qualitygate/small-changesets/v2-1019-lines", true);
105
106     // small leak => if coverage is OK anyways, we do not have to ignore anything
107     tester.wsClient().qualityGates().updateCondition(new UpdateConditionRequest()
108       .setId(String.valueOf(condition.getId()))
109       .setMetric("new_coverage")
110       .setOp("LT")
111       .setWarning("10")
112       .setError("20")
113       .setPeriod("1"));
114     SonarScanner analysis3 = SonarScanner
115       .create(projectDir("qualitygate/small-changesets/v2-1019-lines"))
116       .setProperty("sonar.projectKey", project.getKey())
117       .setProperty("sonar.organization", organization.getKey())
118       .setProperty("sonar.login", user.getLogin())
119       .setProperty("sonar.password", password)
120       .setProperty("sonar.scm.provider", "xoo")
121       .setProperty("sonar.scm.disabled", "false")
122       .setProperty("sonar.projectDate", "2014-04-02")
123       .setDebugLogs(true);
124     orchestrator.executeBuild(analysis3);
125     assertThat(getMeasure(orchestrator, project.getKey(), "alert_status").getValue()).isEqualTo("OK");
126     assertIgnoredConditions("qualitygate/small-changesets/v2-1019-lines", false);
127
128     // big leak => use usual behaviour
129     tester.wsClient().qualityGates().updateCondition(new UpdateConditionRequest()
130       .setId(String.valueOf(condition.getId()))
131       .setMetric("new_coverage")
132       .setOp("LT")
133       .setWarning(null)
134       .setError("70")
135       .setPeriod("1"));
136     SonarScanner analysis4 = SonarScanner
137       .create(projectDir("qualitygate/small-changesets/v2-1020-lines"))
138       .setProperty("sonar.projectKey", project.getKey())
139       .setProperty("sonar.organization", organization.getKey())
140       .setProperty("sonar.login", user.getLogin())
141       .setProperty("sonar.password", password)
142       .setProperty("sonar.scm.provider", "xoo")
143       .setProperty("sonar.scm.disabled", "false")
144       .setProperty("sonar.projectDate", "2014-04-03")
145       .setDebugLogs(true);
146     orchestrator.executeBuild(analysis4);
147     assertThat(getMeasure(orchestrator, project.getKey(), "alert_status").getValue()).isEqualTo("ERROR");
148     assertIgnoredConditions("qualitygate/small-changesets/v2-1020-lines", false);
149   }
150
151   private void assertIgnoredConditions(String projectDir, boolean expected) throws IOException {
152     String analysisId = getAnalysisId(getTaskIdInLocalReport(projectDir(projectDir)));
153     boolean ignoredConditions = tester.wsClient().qualityGates()
154       .projectStatus(new ProjectStatusRequest().setAnalysisId(analysisId))
155       .getProjectStatus()
156       .getIgnoredConditions();
157     assertThat(ignoredConditions).isEqualTo(expected);
158   }
159
160   private String getAnalysisId(String taskId) throws IOException {
161     WsResponse activity = tester.wsClient()
162       .wsConnector()
163       .call(new GetRequest("api/ce/task")
164         .setParam("id", taskId)
165         .setMediaType(MediaTypes.PROTOBUF));
166     Ce.TaskResponse activityWsResponse = Ce.TaskResponse.parseFrom(activity.contentStream());
167     return activityWsResponse.getTask().getAnalysisId();
168   }
169
170   private String getTaskIdInLocalReport(File projectDirectory) throws IOException {
171     File metadata = new File(projectDirectory, ".sonar/report-task.txt");
172     assertThat(metadata).exists().isFile();
173     // verify properties
174     Properties props = new Properties();
175     props.load(new StringReader(FileUtils.readFileToString(metadata, StandardCharsets.UTF_8)));
176     assertThat(props.getProperty("ceTaskId")).isNotEmpty();
177
178     return props.getProperty("ceTaskId");
179   }
180 }