You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ProjectAdministrationTest.java 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. /*
  2. * SonarQube, open source software quality management tool.
  3. * Copyright (C) 2008-2014 SonarSource
  4. * mailto:contact AT sonarsource DOT com
  5. *
  6. * SonarQube 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. * SonarQube 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 administration.suite.administration;
  21. import administration.suite.AdministrationTestSuite;
  22. import com.sonar.orchestrator.Orchestrator;
  23. import com.sonar.orchestrator.build.SonarRunner;
  24. import com.sonar.orchestrator.selenium.Selenese;
  25. import java.sql.SQLException;
  26. import java.util.Calendar;
  27. import java.util.GregorianCalendar;
  28. import javax.annotation.Nullable;
  29. import org.junit.Before;
  30. import org.junit.ClassRule;
  31. import org.junit.Rule;
  32. import org.junit.Test;
  33. import org.junit.rules.ExpectedException;
  34. import org.sonar.wsclient.SonarClient;
  35. import org.sonar.wsclient.base.HttpException;
  36. import org.sonar.wsclient.permissions.PermissionParameters;
  37. import org.sonar.wsclient.qualitygate.NewCondition;
  38. import org.sonar.wsclient.qualitygate.QualityGate;
  39. import org.sonar.wsclient.qualitygate.QualityGateClient;
  40. import org.sonar.wsclient.qualitygate.QualityGateCondition;
  41. import org.sonar.wsclient.qualitygate.UpdateCondition;
  42. import org.sonar.wsclient.services.PropertyQuery;
  43. import org.sonar.wsclient.services.ResourceQuery;
  44. import org.sonar.wsclient.user.UserParameters;
  45. import static org.assertj.core.api.Assertions.assertThat;
  46. import static util.ItUtils.projectDir;
  47. public class ProjectAdministrationTest {
  48. private static final String DELETE_WS_ENDPOINT = "api/projects/bulk_delete";
  49. @ClassRule
  50. public static Orchestrator orchestrator = AdministrationTestSuite.ORCHESTRATOR;
  51. @Rule
  52. public ExpectedException expectedException = ExpectedException.none();
  53. private static final String PROJECT_KEY = "sample";
  54. private static final String FILE_KEY = "sample:src/main/xoo/sample/Sample.xoo";
  55. @Before
  56. public void deleteAnalysisData() throws SQLException {
  57. orchestrator.resetData();
  58. }
  59. @Test
  60. public void delete_project_by_web_service() {
  61. scanSampleWithDate("2012-01-01");
  62. assertThat(orchestrator.getServer().getWsClient().find(ResourceQuery.create(PROJECT_KEY))).isNotNull();
  63. assertThat(orchestrator.getServer().getWsClient().find(ResourceQuery.create(FILE_KEY))).isNotNull();
  64. orchestrator.getServer().adminWsClient().post(DELETE_WS_ENDPOINT, "keys", PROJECT_KEY);
  65. assertThat(orchestrator.getServer().getWsClient().find(ResourceQuery.create(PROJECT_KEY))).isNull();
  66. assertThat(orchestrator.getServer().getWsClient().find(ResourceQuery.create(FILE_KEY))).isNull();
  67. }
  68. @Test
  69. public void fail_when_trying_to_delete_a_file() {
  70. expectedException.expect(HttpException.class);
  71. scanSampleWithDate("2012-01-01");
  72. assertThat(orchestrator.getServer().getWsClient().find(ResourceQuery.create(PROJECT_KEY))).isNotNull();
  73. assertThat(orchestrator.getServer().getWsClient().find(ResourceQuery.create(FILE_KEY))).isNotNull();
  74. // it's forbidden to delete only some files
  75. orchestrator.getServer().adminWsClient().post(DELETE_WS_ENDPOINT, "keys", FILE_KEY);
  76. }
  77. @Test
  78. public void fail_when_insufficient_privilege() {
  79. expectedException.expect(HttpException.class);
  80. scanSampleWithDate("2012-01-01");
  81. assertThat(orchestrator.getServer().getWsClient().find(ResourceQuery.create(PROJECT_KEY))).isNotNull();
  82. // use wsClient() instead of adminWsClient()
  83. orchestrator.getServer().wsClient().post(DELETE_WS_ENDPOINT, "keys", PROJECT_KEY);
  84. }
  85. /**
  86. * Test updated for SONAR-3570 and SONAR-5923
  87. */
  88. @Test
  89. public void project_deletion() throws Exception {
  90. String projectAdminUser = "project-deletion-with-admin-permission-on-project";
  91. SonarClient adminClient = orchestrator.getServer().adminWsClient();
  92. try {
  93. SonarRunner scan = SonarRunner.create(projectDir("shared/xoo-sample"));
  94. orchestrator.executeBuild(scan);
  95. // Create user having admin permission on previously analysed project
  96. adminClient.userClient().create(
  97. UserParameters.create().login(projectAdminUser).name(projectAdminUser).password("password").passwordConfirmation("password"));
  98. adminClient.permissionClient().addPermission(
  99. PermissionParameters.create().user(projectAdminUser).component("sample").permission("admin"));
  100. orchestrator.executeSelenese(
  101. Selenese.builder().setHtmlTestsInClasspath("project-deletion", "/administration/suite/ProjectAdministrationTest/project-deletion/project-deletion.html").build()
  102. );
  103. } finally {
  104. adminClient.userClient().deactivate(projectAdminUser);
  105. }
  106. }
  107. // SONAR-4203
  108. @Test
  109. public void delete_version_of_multimodule_project() throws Exception {
  110. GregorianCalendar today = new GregorianCalendar();
  111. SonarRunner build = SonarRunner.create(projectDir("shared/xoo-multi-modules-sample"))
  112. .setProperty("sonar.dynamicAnalysis", "false")
  113. .setProperty("sonar.projectDate", (today.get(Calendar.YEAR) - 1) + "-01-01");
  114. orchestrator.executeBuild(build);
  115. // The analysis must be run once again to have an history so that it is possible
  116. // to set/delete version on old snapshot
  117. build.setProperty("sonar.projectDate", today.get(Calendar.YEAR) + "-01-01");
  118. orchestrator.executeBuild(build);
  119. // There are 7 modules
  120. assertThat(count("events where category='Version'")).as("Different number of events").isEqualTo(7);
  121. Selenese selenese = Selenese
  122. .builder()
  123. .setHtmlTestsInClasspath("modify_version_of_multimodule_project",
  124. "/administration/suite/ProjectAdministrationTest/project-administration/multimodule-project-modify-version.html"
  125. ).build();
  126. orchestrator.executeSelenese(selenese);
  127. assertThat(count("events where category='Version'")).as("Different number of events").isEqualTo(14);
  128. selenese = Selenese
  129. .builder()
  130. .setHtmlTestsInClasspath("delete_version_of_multimodule_project",
  131. "/administration/suite/ProjectAdministrationTest/project-administration/multimodule-project-delete-version.html"
  132. ).build();
  133. orchestrator.executeSelenese(selenese);
  134. assertThat(count("events where category='Version'")).as("Different number of events").isEqualTo(7);
  135. }
  136. // SONAR-3326
  137. @Test
  138. public void display_alerts_correctly_in_history_page() throws Exception {
  139. QualityGateClient qgClient = orchestrator.getServer().adminWsClient().qualityGateClient();
  140. QualityGate qGate = qgClient.create("AlertsForHistory");
  141. qgClient.setDefault(qGate.id());
  142. // with this configuration, project should have an Orange alert
  143. QualityGateCondition lowThresholds = qgClient.createCondition(NewCondition.create(qGate.id()).metricKey("lines").operator("GT").warningThreshold("5").errorThreshold("50"));
  144. scanSampleWithDate("2012-01-01");
  145. // with this configuration, project should have a Green alert
  146. qgClient.updateCondition(UpdateCondition.create(lowThresholds.id()).metricKey("lines").operator("GT").warningThreshold("5000").errorThreshold("5000"));
  147. scanSampleWithDate("2012-01-02");
  148. Selenese selenese = Selenese
  149. .builder()
  150. .setHtmlTestsInClasspath("display-alerts-history-page",
  151. "/administration/suite/ProjectAdministrationTest/display-alerts-history-page/should-display-alerts-correctly-history-page.html"
  152. ).build();
  153. orchestrator.executeSelenese(selenese);
  154. qgClient.unsetDefault();
  155. qgClient.destroy(qGate.id());
  156. }
  157. /**
  158. * SONAR-1352
  159. */
  160. @Test
  161. public void display_period_alert_on_project_dashboard() throws Exception {
  162. QualityGateClient qgClient = orchestrator.getServer().adminWsClient().qualityGateClient();
  163. QualityGate qGate = qgClient.create("AlertsForDashboard");
  164. qgClient.createCondition(NewCondition.create(qGate.id()).metricKey("lines").operator("LT").warningThreshold("0").errorThreshold("10")
  165. .period(1));
  166. qgClient.setDefault(qGate.id());
  167. // No alert
  168. scanSampleWithDate("2012-01-01");
  169. // Red alert because lines number has not changed since previous analysis
  170. scanSample();
  171. Selenese selenese = Selenese
  172. .builder()
  173. .setHtmlTestsInClasspath("display-period-alerts",
  174. "/administration/suite/ProjectAdministrationTest/display-alerts/should-display-period-alerts-correctly.html"
  175. ).build();
  176. orchestrator.executeSelenese(selenese);
  177. qgClient.unsetDefault();
  178. qgClient.destroy(qGate.id());
  179. }
  180. /**
  181. * SONAR-3425
  182. */
  183. @Test
  184. public void project_settings() {
  185. scanSampleWithDate("2012-01-01");
  186. Selenese selenese = Selenese.builder().setHtmlTestsInClasspath("project-settings",
  187. // SONAR-3425
  188. "/administration/suite/ProjectAdministrationTest/project-settings/override-global-settings.html",
  189. "/administration/suite/ProjectAdministrationTest/project-settings/only-on-project-settings.html"
  190. ).build();
  191. orchestrator.executeSelenese(selenese);
  192. assertThat(orchestrator.getServer().getAdminWsClient().find(PropertyQuery.createForResource("sonar.skippedModules", "sample")).getValue())
  193. .isEqualTo("my-excluded-module");
  194. }
  195. /**
  196. * SONAR-1608
  197. */
  198. @Test
  199. public void bulk_update_project_keys() {
  200. SonarRunner build = SonarRunner.create(projectDir("shared/xoo-multi-modules-sample"));
  201. orchestrator.executeBuild(build);
  202. Selenese selenese = Selenese
  203. .builder()
  204. .setHtmlTestsInClasspath("project-bulk-update-keys",
  205. "/administration/suite/ProjectAdministrationTest/project-update-keys/bulk-update-impossible-because-duplicate-keys.html",
  206. "/administration/suite/ProjectAdministrationTest/project-update-keys/bulk-update-impossible-because-no-input.html",
  207. "/administration/suite/ProjectAdministrationTest/project-update-keys/bulk-update-impossible-because-no-match.html",
  208. "/administration/suite/ProjectAdministrationTest/project-update-keys/bulk-update-success.html"
  209. ).build();
  210. orchestrator.executeSelenese(selenese);
  211. }
  212. /**
  213. * SONAR-1608
  214. */
  215. @Test
  216. public void fine_grain_update_project_keys() {
  217. SonarRunner build = SonarRunner.create(projectDir("shared/xoo-multi-modules-sample"));
  218. orchestrator.executeBuild(build);
  219. Selenese selenese = Selenese
  220. .builder()
  221. .setHtmlTestsInClasspath("project-fine-grained-update-keys",
  222. "/administration/suite/ProjectAdministrationTest/project-update-keys/fine-grained-update-impossible.html",
  223. "/administration/suite/ProjectAdministrationTest/project-update-keys/fine-grained-update-success.html"
  224. ).build();
  225. orchestrator.executeSelenese(selenese);
  226. }
  227. @Test
  228. public void anonymous_should_have_user_role_to_access_project() {
  229. scanSample();
  230. Selenese selenese = Selenese.builder()
  231. .setHtmlTestsInClasspath("anonymous_should_have_user_role_to_access_project",
  232. "/administration/suite/ProjectAdministrationTest/anonymous_should_have_user_role_to_access_project/remove_user_role.html"
  233. ).build();
  234. orchestrator.executeSelenese(selenese);
  235. }
  236. /**
  237. * SONAR-4060
  238. */
  239. @Test
  240. public void display_module_settings() {
  241. orchestrator.executeBuild(SonarRunner.create(projectDir("shared/xoo-multi-modules-sample")));
  242. Selenese selenese = Selenese.builder().setHtmlTestsInClasspath("module-settings",
  243. // SONAR-3425
  244. "/administration/suite/ProjectAdministrationTest/module-settings/display-module-settings.html"
  245. ).build();
  246. orchestrator.executeSelenese(selenese);
  247. }
  248. private void scanSample() {
  249. scanSample(null, null);
  250. }
  251. private void scanSampleWithDate(String date) {
  252. scanSample(date, null);
  253. }
  254. private void scanSample(@Nullable String date, @Nullable String profile) {
  255. SonarRunner scan = SonarRunner.create(projectDir("shared/xoo-sample"))
  256. .setProperties("sonar.cpd.skip", "true");
  257. if (date != null) {
  258. scan.setProperty("sonar.projectDate", date);
  259. }
  260. if (profile != null) {
  261. scan.setProfile(profile);
  262. }
  263. orchestrator.executeBuild(scan);
  264. }
  265. private int count(String condition) {
  266. return orchestrator.getDatabase().countSql("select count(*) from " + condition);
  267. }
  268. }