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.

ComponentKeyUpdaterDaoTest.java 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2018 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.sonar.db.component;
  21. import com.google.common.base.Strings;
  22. import java.util.List;
  23. import java.util.Map;
  24. import org.junit.Rule;
  25. import org.junit.Test;
  26. import org.junit.rules.ExpectedException;
  27. import org.sonar.api.utils.System2;
  28. import org.sonar.db.DbClient;
  29. import org.sonar.db.DbSession;
  30. import org.sonar.db.DbTester;
  31. import org.sonar.db.organization.OrganizationDto;
  32. import static com.google.common.collect.Lists.newArrayList;
  33. import static org.assertj.core.api.Assertions.assertThat;
  34. import static org.assertj.core.api.Assertions.entry;
  35. import static org.sonar.db.component.BranchType.PULL_REQUEST;
  36. import static org.sonar.db.component.ComponentKeyUpdaterDao.computeNewKey;
  37. import static org.sonar.db.component.ComponentTesting.newDirectory;
  38. import static org.sonar.db.component.ComponentTesting.newFileDto;
  39. import static org.sonar.db.component.ComponentTesting.newModuleDto;
  40. import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto;
  41. public class ComponentKeyUpdaterDaoTest {
  42. @Rule
  43. public ExpectedException thrown = ExpectedException.none();
  44. @Rule
  45. public DbTester db = DbTester.create(System2.INSTANCE);
  46. private DbClient dbClient = db.getDbClient();
  47. private DbSession dbSession = db.getSession();
  48. private ComponentKeyUpdaterDao underTest = db.getDbClient().componentKeyUpdaterDao();
  49. @Test
  50. public void updateKey_changes_the_key_of_tree_of_components() {
  51. db.prepareDbUnit(getClass(), "shared.xml");
  52. underTest.updateKey(dbSession, "B", "struts:core");
  53. dbSession.commit();
  54. db.assertDbUnit(getClass(), "shouldUpdateKey-result.xml", "projects");
  55. }
  56. @Test
  57. public void updateKey_does_not_update_inactive_components() {
  58. OrganizationDto organizationDto = db.organizations().insert();
  59. ComponentDto project = db.components().insertComponent(newPrivateProjectDto(organizationDto, "A").setDbKey("my_project"));
  60. ComponentDto directory = db.components().insertComponent(newDirectory(project, "/directory").setDbKey("my_project:directory"));
  61. db.components().insertComponent(newFileDto(project, directory).setDbKey("my_project:directory/file"));
  62. ComponentDto inactiveDirectory = db.components().insertComponent(newDirectory(project, "/inactive_directory").setDbKey("my_project:inactive_directory").setEnabled(false));
  63. db.components().insertComponent(newFileDto(project, inactiveDirectory).setDbKey("my_project:inactive_directory/file").setEnabled(false));
  64. underTest.updateKey(dbSession, "A", "your_project");
  65. dbSession.commit();
  66. List<ComponentDto> result = dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, "your_project");
  67. assertThat(result).hasSize(5).extracting(ComponentDto::getDbKey)
  68. .containsOnlyOnce("your_project", "your_project:directory", "your_project:directory/file", "my_project:inactive_directory", "my_project:inactive_directory/file");
  69. }
  70. @Test
  71. public void updateKey_updates_branches_too() {
  72. ComponentDto project = db.components().insertMainBranch();
  73. ComponentDto branch = db.components().insertProjectBranch(project);
  74. db.components().insertComponent(newFileDto(branch));
  75. db.components().insertComponent(newFileDto(branch));
  76. int branchComponentCount = 3;
  77. String oldProjectKey = project.getKey();
  78. assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, oldProjectKey)).hasSize(1);
  79. String oldBranchKey = branch.getDbKey();
  80. assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, oldBranchKey)).hasSize(branchComponentCount);
  81. String newProjectKey = "newKey";
  82. String newBranchKey = ComponentDto.generateBranchKey(newProjectKey, branch.getBranch());
  83. underTest.updateKey(dbSession, project.uuid(), newProjectKey);
  84. assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, oldProjectKey)).isEmpty();
  85. assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, oldBranchKey)).isEmpty();
  86. assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, newProjectKey)).hasSize(1);
  87. assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, newBranchKey)).hasSize(branchComponentCount);
  88. db.select(dbSession, "select kee from projects")
  89. .forEach(map -> map.values().forEach(k -> assertThat(k.toString()).startsWith(newProjectKey)));
  90. }
  91. @Test
  92. public void updateKey_updates_pull_requests_too() {
  93. ComponentDto project = db.components().insertMainBranch();
  94. ComponentDto pullRequest = db.components().insertProjectBranch(project, b -> b.setBranchType(PULL_REQUEST));
  95. db.components().insertComponent(newFileDto(pullRequest));
  96. db.components().insertComponent(newFileDto(pullRequest));
  97. int branchComponentCount = 3;
  98. String oldProjectKey = project.getKey();
  99. assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, oldProjectKey)).hasSize(1);
  100. String oldBranchKey = pullRequest.getDbKey();
  101. assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, oldBranchKey)).hasSize(branchComponentCount);
  102. String newProjectKey = "newKey";
  103. String newBranchKey = ComponentDto.generatePullRequestKey(newProjectKey, pullRequest.getPullRequest());
  104. underTest.updateKey(dbSession, project.uuid(), newProjectKey);
  105. assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, oldProjectKey)).isEmpty();
  106. assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, oldBranchKey)).isEmpty();
  107. assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, newProjectKey)).hasSize(1);
  108. assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, newBranchKey)).hasSize(branchComponentCount);
  109. db.select(dbSession, "select kee from projects")
  110. .forEach(map -> map.values().forEach(k -> assertThat(k.toString()).startsWith(newProjectKey)));
  111. }
  112. @Test
  113. public void bulk_updateKey_updates_branches_too() {
  114. ComponentDto project = db.components().insertMainBranch();
  115. ComponentDto branch = db.components().insertProjectBranch(project);
  116. ComponentDto module = db.components().insertComponent(prefixDbKeyWithKey(newModuleDto(branch), project.getKey()));
  117. db.components().insertComponent(prefixDbKeyWithKey(newFileDto(module), module.getKey()));
  118. db.components().insertComponent(prefixDbKeyWithKey(newFileDto(module), module.getKey()));
  119. int branchComponentCount = 4;
  120. String oldProjectKey = project.getKey();
  121. assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, oldProjectKey)).hasSize(1);
  122. String oldBranchKey = branch.getDbKey();
  123. assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, oldBranchKey)).hasSize(branchComponentCount);
  124. String newProjectKey = "newKey";
  125. String newBranchKey = ComponentDto.generateBranchKey(newProjectKey, branch.getBranch());
  126. underTest.bulkUpdateKey(dbSession, project.uuid(), oldProjectKey, newProjectKey);
  127. assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, oldProjectKey)).isEmpty();
  128. assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, oldBranchKey)).isEmpty();
  129. assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, newProjectKey)).hasSize(1);
  130. assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, newBranchKey)).hasSize(branchComponentCount);
  131. db.select(dbSession, "select kee from projects")
  132. .forEach(map -> map.values().forEach(k -> assertThat(k.toString()).startsWith(newProjectKey)));
  133. }
  134. @Test
  135. public void bulk_updateKey_updates_pull_requests_too() {
  136. ComponentDto project = db.components().insertMainBranch();
  137. ComponentDto pullRequest = db.components().insertProjectBranch(project, b -> b.setBranchType(PULL_REQUEST));
  138. ComponentDto module = db.components().insertComponent(prefixDbKeyWithKey(newModuleDto(pullRequest), project.getKey()));
  139. db.components().insertComponent(prefixDbKeyWithKey(newFileDto(module), module.getKey()));
  140. db.components().insertComponent(prefixDbKeyWithKey(newFileDto(module), module.getKey()));
  141. int branchComponentCount = 4;
  142. String oldProjectKey = project.getKey();
  143. assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, oldProjectKey)).hasSize(1);
  144. String oldPullRequestKey = pullRequest.getDbKey();
  145. assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, oldPullRequestKey)).hasSize(branchComponentCount);
  146. String newProjectKey = "newKey";
  147. String newPullRequestKey = ComponentDto.generatePullRequestKey(newProjectKey, pullRequest.getPullRequest());
  148. underTest.bulkUpdateKey(dbSession, project.uuid(), oldProjectKey, newProjectKey);
  149. assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, oldProjectKey)).isEmpty();
  150. assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, oldPullRequestKey)).isEmpty();
  151. assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, newProjectKey)).hasSize(1);
  152. assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, newPullRequestKey)).hasSize(branchComponentCount);
  153. db.select(dbSession, "select kee from projects")
  154. .forEach(map -> map.values().forEach(k -> assertThat(k.toString()).startsWith(newProjectKey)));
  155. }
  156. private ComponentDto prefixDbKeyWithKey(ComponentDto componentDto, String key) {
  157. return componentDto.setDbKey(key + ":" + componentDto.getDbKey());
  158. }
  159. @Test
  160. public void updateKey_throws_IAE_if_component_with_specified_key_does_not_exist() {
  161. db.prepareDbUnit(getClass(), "shared.xml");
  162. thrown.expect(IllegalArgumentException.class);
  163. thrown.expectMessage("Impossible to update key: a component with key \"org.struts:struts-ui\" already exists.");
  164. underTest.updateKey(dbSession, "B", "org.struts:struts-ui");
  165. }
  166. @Test
  167. public void bulk_update_key_does_not_update_inactive_components() {
  168. ComponentDto project = db.components().insertComponent(newPrivateProjectDto(db.getDefaultOrganization(), "A").setDbKey("my_project"));
  169. db.components().insertComponent(newModuleDto(project).setDbKey("my_project:module"));
  170. db.components().insertComponent(newModuleDto(project).setDbKey("my_project:inactive_module").setEnabled(false));
  171. underTest.bulkUpdateKey(dbSession, "A", "my_", "your_");
  172. List<ComponentDto> result = dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, "your_project");
  173. assertThat(result).hasSize(3).extracting(ComponentDto::getDbKey)
  174. .containsOnlyOnce("your_project", "your_project:module", "my_project:inactive_module");
  175. }
  176. @Test
  177. public void shouldBulkUpdateKey() {
  178. db.prepareDbUnit(getClass(), "shared.xml");
  179. underTest.bulkUpdateKey(dbSession, "A", "org.struts", "org.apache.struts");
  180. dbSession.commit();
  181. db.assertDbUnit(getClass(), "shouldBulkUpdateKey-result.xml", "projects");
  182. }
  183. @Test
  184. public void shouldBulkUpdateKeyOnOnlyOneSubmodule() {
  185. db.prepareDbUnit(getClass(), "shared.xml");
  186. underTest.bulkUpdateKey(dbSession, "A", "struts-ui", "struts-web");
  187. dbSession.commit();
  188. db.assertDbUnit(getClass(), "shouldBulkUpdateKeyOnOnlyOneSubmodule-result.xml", "projects");
  189. }
  190. @Test
  191. public void shouldFailBulkUpdateKeyIfKeyAlreadyExist() {
  192. db.prepareDbUnit(getClass(), "shared.xml");
  193. thrown.expect(IllegalArgumentException.class);
  194. thrown.expectMessage("Impossible to update key: a component with key \"foo:struts-core\" already exists.");
  195. underTest.bulkUpdateKey(dbSession, "A", "org.struts", "foo");
  196. dbSession.commit();
  197. }
  198. @Test
  199. public void shouldNotUpdateAllSubmodules() {
  200. db.prepareDbUnit(getClass(), "shouldNotUpdateAllSubmodules.xml");
  201. underTest.bulkUpdateKey(dbSession, "A", "org.struts", "org.apache.struts");
  202. dbSession.commit();
  203. db.assertDbUnit(getClass(), "shouldNotUpdateAllSubmodules-result.xml", "projects");
  204. }
  205. @Test
  206. public void updateKey_throws_IAE_when_sub_component_key_is_too_long() {
  207. OrganizationDto organizationDto = db.organizations().insert();
  208. ComponentDto project = newPrivateProjectDto(organizationDto, "project-uuid").setDbKey("old-project-key");
  209. db.components().insertComponent(project);
  210. db.components().insertComponent(newFileDto(project, null).setDbKey("old-project-key:file"));
  211. String newLongProjectKey = Strings.repeat("a", 400);
  212. thrown.expect(IllegalArgumentException.class);
  213. thrown.expectMessage("Component key length (405) is longer than the maximum authorized (400). '" + newLongProjectKey + ":file' was provided.");
  214. underTest.updateKey(dbSession, project.uuid(), newLongProjectKey);
  215. }
  216. @Test
  217. public void fail_when_new_key_is_invalid() {
  218. ComponentDto project = db.components().insertPrivateProject();
  219. thrown.expect(IllegalArgumentException.class);
  220. thrown.expectMessage("Malformed key for 'my?project?key'. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.");
  221. underTest.bulkUpdateKey(dbSession, project.uuid(), project.getDbKey(), "my?project?key");
  222. }
  223. @Test
  224. public void check_component_keys() {
  225. db.prepareDbUnit(getClass(), "shared.xml");
  226. Map<String, Boolean> result = underTest.checkComponentKeys(dbSession, newArrayList("foo:struts", "foo:struts-core", "foo:struts-ui"));
  227. assertThat(result)
  228. .hasSize(3)
  229. .containsOnly(entry("foo:struts", false), entry("foo:struts-core", true), entry("foo:struts-ui", false));
  230. }
  231. @Test
  232. public void check_component_keys_checks_inactive_components() {
  233. OrganizationDto organizationDto = db.organizations().insert();
  234. db.components().insertComponent(ComponentTesting.newPrivateProjectDto(organizationDto).setDbKey("my-project"));
  235. db.components().insertComponent(ComponentTesting.newPrivateProjectDto(organizationDto).setDbKey("your-project").setEnabled(false));
  236. Map<String, Boolean> result = underTest.checkComponentKeys(dbSession, newArrayList("my-project", "your-project", "new-project"));
  237. assertThat(result)
  238. .hasSize(3)
  239. .containsOnly(entry("my-project", true), entry("your-project", true), entry("new-project", false));
  240. }
  241. @Test
  242. public void simulate_bulk_update_key() {
  243. db.prepareDbUnit(getClass(), "shared.xml");
  244. Map<String, String> result = underTest.simulateBulkUpdateKey(dbSession, "A", "org.struts", "foo");
  245. assertThat(result)
  246. .hasSize(3)
  247. .containsOnly(entry("org.struts:struts", "foo:struts"), entry("org.struts:struts-core", "foo:struts-core"), entry("org.struts:struts-ui", "foo:struts-ui"));
  248. }
  249. @Test
  250. public void simulate_bulk_update_key_do_not_return_disable_components() {
  251. ComponentDto project = db.components().insertComponent(newPrivateProjectDto(db.getDefaultOrganization(), "A").setDbKey("project"));
  252. db.components().insertComponent(newModuleDto(project).setDbKey("project:enabled-module"));
  253. db.components().insertComponent(newModuleDto(project).setDbKey("project:disabled-module").setEnabled(false));
  254. Map<String, String> result = underTest.simulateBulkUpdateKey(dbSession, "A", "project", "new-project");
  255. assertThat(result)
  256. .hasSize(2)
  257. .containsOnly(entry("project", "new-project"), entry("project:enabled-module", "new-project:enabled-module"));
  258. }
  259. @Test
  260. public void simulate_bulk_update_key_fails_if_invalid_componentKey() {
  261. OrganizationDto organizationDto = db.organizations().insert();
  262. ComponentDto project = db.components().insertComponent(newPrivateProjectDto(organizationDto, "A").setDbKey("project"));
  263. db.components().insertComponent(newModuleDto(project).setDbKey("project:enabled-module"));
  264. db.components().insertComponent(newModuleDto(project).setDbKey("project:disabled-module").setEnabled(false));
  265. thrown.expect(IllegalArgumentException.class);
  266. underTest.simulateBulkUpdateKey(dbSession, "A", "project", "project?");
  267. }
  268. @Test
  269. public void compute_new_key() {
  270. assertThat(computeNewKey("my_project", "my_", "your_")).isEqualTo("your_project");
  271. assertThat(computeNewKey("my_project", "my_", "$()_")).isEqualTo("$()_project");
  272. }
  273. }