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.

FileSourceDaoTest.java 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2021 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.source;
  21. import com.google.common.collect.ImmutableList;
  22. import com.google.common.collect.ImmutableSet;
  23. import java.util.ArrayList;
  24. import java.util.List;
  25. import java.util.Optional;
  26. import java.util.Random;
  27. import java.util.stream.Collectors;
  28. import java.util.stream.IntStream;
  29. import org.apache.ibatis.session.ResultContext;
  30. import org.apache.ibatis.session.ResultHandler;
  31. import org.junit.Rule;
  32. import org.junit.Test;
  33. import org.sonar.api.utils.System2;
  34. import org.sonar.core.util.Uuids;
  35. import org.sonar.db.DbSession;
  36. import org.sonar.db.DbTester;
  37. import org.sonar.db.component.ComponentDto;
  38. import static com.google.common.collect.ImmutableList.of;
  39. import static java.util.Collections.emptyList;
  40. import static java.util.Collections.emptySet;
  41. import static java.util.Collections.singletonList;
  42. import static org.assertj.core.api.Assertions.assertThat;
  43. import static org.assertj.core.api.Assertions.fail;
  44. import static org.sonar.db.component.ComponentTesting.newFileDto;
  45. public class FileSourceDaoTest {
  46. @Rule
  47. public DbTester dbTester = DbTester.create(System2.INSTANCE);
  48. private final DbSession dbSession = dbTester.getSession();
  49. private final FileSourceDao underTest = dbTester.getDbClient().fileSourceDao();
  50. @Test
  51. public void select() {
  52. ComponentDto project = dbTester.components().insertPrivateProject();
  53. ComponentDto file = dbTester.components().insertComponent(newFileDto(project));
  54. FileSourceDto expected = dbTester.fileSources().insertFileSource(file);
  55. FileSourceDto fileSourceDto = underTest.selectByFileUuid(dbSession, file.uuid());
  56. assertThat(fileSourceDto.getBinaryData()).isEqualTo(expected.getBinaryData());
  57. assertThat(fileSourceDto.getDataHash()).isEqualTo(expected.getDataHash());
  58. assertThat(fileSourceDto.getProjectUuid()).isEqualTo(expected.getProjectUuid());
  59. assertThat(fileSourceDto.getFileUuid()).isEqualTo(expected.getFileUuid());
  60. assertThat(fileSourceDto.getCreatedAt()).isEqualTo(expected.getCreatedAt());
  61. assertThat(fileSourceDto.getUpdatedAt()).isEqualTo(expected.getUpdatedAt());
  62. assertThat(fileSourceDto.getRevision()).isEqualTo(expected.getRevision());
  63. assertThat(fileSourceDto.getLineHashesVersion()).isEqualTo(expected.getLineHashesVersion());
  64. assertThat(fileSourceDto.getLineHashes()).isEqualTo(expected.getLineHashes());
  65. }
  66. @Test
  67. public void insert() {
  68. FileSourceDto expected = new FileSourceDto()
  69. .setUuid(Uuids.createFast())
  70. .setProjectUuid("PRJ_UUID")
  71. .setFileUuid("FILE2_UUID")
  72. .setBinaryData("FILE2_BINARY_DATA".getBytes())
  73. .setDataHash("FILE2_DATA_HASH")
  74. .setLineHashes(of("LINE1_HASH", "LINE2_HASH"))
  75. .setSrcHash("FILE2_HASH")
  76. .setCreatedAt(1500000000000L)
  77. .setUpdatedAt(1500000000001L)
  78. .setLineHashesVersion(1)
  79. .setRevision("123456789");
  80. underTest.insert(dbSession, expected);
  81. dbSession.commit();
  82. FileSourceDto fileSourceDto = underTest.selectByFileUuid(dbSession, expected.getFileUuid());
  83. assertThat(fileSourceDto.getProjectUuid()).isEqualTo(expected.getProjectUuid());
  84. assertThat(fileSourceDto.getFileUuid()).isEqualTo(expected.getFileUuid());
  85. assertThat(fileSourceDto.getBinaryData()).isEqualTo(expected.getBinaryData());
  86. assertThat(fileSourceDto.getDataHash()).isEqualTo(expected.getDataHash());
  87. assertThat(fileSourceDto.getRawLineHashes()).isEqualTo(expected.getRawLineHashes());
  88. assertThat(fileSourceDto.getLineHashes()).isEqualTo(expected.getLineHashes());
  89. assertThat(fileSourceDto.getLineCount()).isEqualTo(expected.getLineCount());
  90. assertThat(fileSourceDto.getSrcHash()).isEqualTo(expected.getSrcHash());
  91. assertThat(fileSourceDto.getCreatedAt()).isEqualTo(expected.getCreatedAt());
  92. assertThat(fileSourceDto.getUpdatedAt()).isEqualTo(expected.getUpdatedAt());
  93. assertThat(fileSourceDto.getRevision()).isEqualTo(expected.getRevision());
  94. }
  95. @Test
  96. public void insert_does_not_fail_on_FileSourceDto_with_only_non_nullable_data() {
  97. FileSourceDto fileSourceDto = new FileSourceDto()
  98. .setUuid(Uuids.createFast())
  99. .setProjectUuid("Foo")
  100. .setFileUuid("Bar")
  101. .setCreatedAt(1500000000000L)
  102. .setUpdatedAt(1500000000001L);
  103. underTest.insert(dbSession, fileSourceDto);
  104. dbSession.commit();
  105. }
  106. @Test
  107. public void selectSourceByFileUuid_reads_source_without_line_hashes() {
  108. FileSourceDto fileSourceDto = new FileSourceDto()
  109. .setUuid(Uuids.createFast())
  110. .setProjectUuid("Foo")
  111. .setFileUuid("Bar")
  112. .setCreatedAt(1500000000000L)
  113. .setUpdatedAt(1500000000001L);
  114. underTest.insert(dbSession, fileSourceDto);
  115. dbSession.commit();
  116. FileSourceDto res = underTest.selectByFileUuid(dbSession, fileSourceDto.getFileUuid());
  117. assertThat(res.getLineCount()).isZero();
  118. assertThat(res.getLineHashes()).isEmpty();
  119. }
  120. @Test
  121. public void selectLineHashes_does_not_fail_when_lineshashes_is_null() {
  122. underTest.insert(dbSession, new FileSourceDto()
  123. .setUuid(Uuids.createFast())
  124. .setProjectUuid("PRJ_UUID")
  125. .setFileUuid("FILE2_UUID")
  126. .setBinaryData("FILE2_BINARY_DATA".getBytes())
  127. .setDataHash("FILE2_DATA_HASH")
  128. .setSrcHash("FILE2_HASH")
  129. .setCreatedAt(1500000000000L)
  130. .setUpdatedAt(1500000000001L)
  131. .setRevision("123456789"));
  132. dbSession.commit();
  133. assertThat(underTest.selectLineHashes(dbSession, "FILE2_UUID")).isEmpty();
  134. }
  135. @Test
  136. public void selectLineHashesVersion_returns_without_significant_code_by_default() {
  137. underTest.insert(dbSession, new FileSourceDto()
  138. .setUuid(Uuids.createFast())
  139. .setProjectUuid("PRJ_UUID")
  140. .setFileUuid("FILE2_UUID")
  141. .setBinaryData("FILE2_BINARY_DATA".getBytes())
  142. .setDataHash("FILE2_DATA_HASH")
  143. .setLineHashes(singletonList("hashes"))
  144. .setSrcHash("FILE2_HASH")
  145. .setCreatedAt(1500000000000L)
  146. .setUpdatedAt(1500000000001L)
  147. .setRevision("123456789"));
  148. dbSession.commit();
  149. assertThat(underTest.selectLineHashesVersion(dbSession, "FILE2_UUID")).isEqualTo(LineHashVersion.WITHOUT_SIGNIFICANT_CODE);
  150. }
  151. @Test
  152. public void selectLineHashesVersion_succeeds() {
  153. underTest.insert(dbSession, new FileSourceDto()
  154. .setUuid(Uuids.createFast())
  155. .setProjectUuid("PRJ_UUID")
  156. .setFileUuid("FILE2_UUID")
  157. .setBinaryData("FILE2_BINARY_DATA".getBytes())
  158. .setDataHash("FILE2_DATA_HASH")
  159. .setLineHashes(singletonList("hashes"))
  160. .setSrcHash("FILE2_HASH")
  161. .setCreatedAt(1500000000000L)
  162. .setUpdatedAt(1500000000001L)
  163. .setLineHashesVersion(1)
  164. .setRevision("123456789"));
  165. dbSession.commit();
  166. assertThat(underTest.selectLineHashesVersion(dbSession, "FILE2_UUID")).isEqualTo(LineHashVersion.WITH_SIGNIFICANT_CODE);
  167. }
  168. @Test
  169. public void scrollLineHashes_has_no_effect_if_no_uuids() {
  170. underTest.scrollLineHashes(dbSession, emptySet(), resultContext -> fail("handler should not be called"));
  171. }
  172. @Test
  173. public void scrollLineHashes_scrolls_hashes_of_specific_keys() {
  174. ComponentDto project = new Random().nextBoolean() ? dbTester.components().insertPrivateProject() : dbTester.components().insertPublicProject();
  175. ComponentDto file1 = dbTester.components().insertComponent(newFileDto(project));
  176. FileSourceDto fileSource1 = dbTester.fileSources().insertFileSource(file1);
  177. ComponentDto file2 = dbTester.components().insertComponent(newFileDto(project));
  178. FileSourceDto fileSource2 = dbTester.fileSources().insertFileSource(file2);
  179. ComponentDto file3 = dbTester.components().insertComponent(newFileDto(project));
  180. FileSourceDto fileSource3 = dbTester.fileSources().insertFileSource(file3);
  181. LineHashesWithKeyDtoHandler handler = scrollLineHashes(file1.uuid());
  182. assertThat(handler.dtos).hasSize(1);
  183. verifyLinesHashes(handler, file1, fileSource1);
  184. handler = scrollLineHashes(file2.uuid());
  185. assertThat(handler.dtos).hasSize(1);
  186. verifyLinesHashes(handler, file2, fileSource2);
  187. handler = scrollLineHashes(file2.uuid(), file1.uuid(), file3.uuid());
  188. assertThat(handler.dtos).hasSize(3);
  189. verifyLinesHashes(handler, file1, fileSource1);
  190. verifyLinesHashes(handler, file2, fileSource2);
  191. verifyLinesHashes(handler, file3, fileSource3);
  192. }
  193. @Test
  194. public void scrollLineHashes_does_not_scroll_hashes_of_component_without_path() {
  195. ComponentDto project = new Random().nextBoolean() ? dbTester.components().insertPrivateProject() : dbTester.components().insertPublicProject();
  196. ComponentDto file1 = dbTester.components().insertComponent(newFileDto(project));
  197. FileSourceDto fileSource1 = dbTester.fileSources().insertFileSource(file1);
  198. ComponentDto file2 = dbTester.components().insertComponent(newFileDto(project).setPath(null));
  199. FileSourceDto fileSource2 = dbTester.fileSources().insertFileSource(file2);
  200. LineHashesWithKeyDtoHandler handler = scrollLineHashes(file2.uuid(), file1.uuid());
  201. assertThat(handler.dtos).hasSize(1);
  202. verifyLinesHashes(handler, file1, fileSource1);
  203. }
  204. @Test
  205. public void scrollLineHashes_handles_scrolling_more_than_1000_files() {
  206. ComponentDto project = new Random().nextBoolean() ? dbTester.components().insertPrivateProject() : dbTester.components().insertPublicProject();
  207. List<ComponentDto> files = IntStream.range(0, 1001 + new Random().nextInt(5))
  208. .mapToObj(i -> {
  209. ComponentDto file = dbTester.components().insertComponent(newFileDto(project));
  210. dbTester.fileSources().insertFileSource(file);
  211. return file;
  212. })
  213. .collect(Collectors.toList());
  214. LineHashesWithKeyDtoHandler handler = new LineHashesWithKeyDtoHandler();
  215. underTest.scrollLineHashes(dbSession, files.stream().map(ComponentDto::uuid).collect(Collectors.toSet()), handler);
  216. assertThat(handler.dtos).hasSize(files.size());
  217. files.forEach(t -> assertThat(handler.getByUuid(t.uuid())).isPresent());
  218. }
  219. private LineHashesWithKeyDtoHandler scrollLineHashes(String... uuids) {
  220. LineHashesWithKeyDtoHandler handler = new LineHashesWithKeyDtoHandler();
  221. underTest.scrollLineHashes(dbSession, ImmutableSet.copyOf(uuids), handler);
  222. return handler;
  223. }
  224. private static void verifyLinesHashes(LineHashesWithKeyDtoHandler handler, ComponentDto file, FileSourceDto fileSource) {
  225. LineHashesWithUuidDto dto = handler.getByUuid(file.uuid()).get();
  226. assertThat(dto.getPath()).isEqualTo(file.path());
  227. assertThat(dto.getRawLineHashes()).isEqualTo(fileSource.getRawLineHashes());
  228. assertThat(dto.getLineHashes()).isEqualTo(fileSource.getLineHashes());
  229. }
  230. private static final class LineHashesWithKeyDtoHandler implements ResultHandler<LineHashesWithUuidDto> {
  231. private final List<LineHashesWithUuidDto> dtos = new ArrayList<>();
  232. @Override
  233. public void handleResult(ResultContext<? extends LineHashesWithUuidDto> resultContext) {
  234. dtos.add(resultContext.getResultObject());
  235. }
  236. public Optional<LineHashesWithUuidDto> getByUuid(String uuid) {
  237. return dtos.stream()
  238. .filter(t -> uuid.equals(t.getUuid()))
  239. .findAny();
  240. }
  241. }
  242. @Test
  243. public void update() {
  244. ComponentDto project = dbTester.components().insertPrivateProject();
  245. ComponentDto file = dbTester.components().insertComponent(newFileDto(project));
  246. FileSourceDto expected = dbTester.fileSources().insertFileSource(file);
  247. underTest.update(dbSession, new FileSourceDto()
  248. .setUuid(expected.getUuid())
  249. .setProjectUuid("PRJ_UUID")
  250. .setFileUuid("FILE1_UUID")
  251. .setBinaryData("updated data".getBytes())
  252. .setDataHash("NEW_DATA_HASH")
  253. .setSrcHash("NEW_FILE_HASH")
  254. .setLineHashes(singletonList("NEW_LINE_HASHES"))
  255. .setUpdatedAt(1500000000002L)
  256. .setLineHashesVersion(1)
  257. .setRevision("987654321"));
  258. dbSession.commit();
  259. FileSourceDto fileSourceDto = underTest.selectByFileUuid(dbSession, file.uuid());
  260. assertThat(fileSourceDto.getProjectUuid()).isEqualTo(expected.getProjectUuid());
  261. assertThat(fileSourceDto.getFileUuid()).isEqualTo(expected.getFileUuid());
  262. assertThat(fileSourceDto.getBinaryData()).isEqualTo("updated data".getBytes());
  263. assertThat(fileSourceDto.getDataHash()).isEqualTo("NEW_DATA_HASH");
  264. assertThat(fileSourceDto.getRawLineHashes()).isEqualTo("NEW_LINE_HASHES");
  265. assertThat(fileSourceDto.getLineHashes()).isEqualTo(singletonList("NEW_LINE_HASHES"));
  266. assertThat(fileSourceDto.getLineCount()).isEqualTo(1);
  267. assertThat(fileSourceDto.getSrcHash()).isEqualTo("NEW_FILE_HASH");
  268. assertThat(fileSourceDto.getCreatedAt()).isEqualTo(expected.getCreatedAt());
  269. assertThat(fileSourceDto.getUpdatedAt()).isEqualTo(1500000000002L);
  270. assertThat(fileSourceDto.getRevision()).isEqualTo("987654321");
  271. }
  272. @Test
  273. public void update_to_no_line_hashes() {
  274. ImmutableList<String> lineHashes = of("a", "b", "c");
  275. FileSourceDto fileSourceDto = new FileSourceDto()
  276. .setUuid(Uuids.createFast())
  277. .setProjectUuid("Foo")
  278. .setFileUuid("Bar")
  279. .setLineHashes(lineHashes)
  280. .setCreatedAt(1500000000000L)
  281. .setUpdatedAt(1500000000001L);
  282. underTest.insert(dbSession, fileSourceDto);
  283. dbSession.commit();
  284. FileSourceDto resBefore = underTest.selectByFileUuid(dbSession, fileSourceDto.getFileUuid());
  285. assertThat(resBefore.getLineCount()).isEqualTo(lineHashes.size());
  286. assertThat(resBefore.getLineHashes()).isEqualTo(lineHashes);
  287. fileSourceDto.setUuid(resBefore.getUuid());
  288. fileSourceDto.setLineHashes(emptyList());
  289. underTest.update(dbSession, fileSourceDto);
  290. dbSession.commit();
  291. FileSourceDto res = underTest.selectByFileUuid(dbSession, fileSourceDto.getFileUuid());
  292. assertThat(res.getLineHashes()).isEmpty();
  293. assertThat(res.getLineCount()).isEqualTo(1);
  294. }
  295. }