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.

LiveMeasureDaoTest.java 26KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2019 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.measure;
  21. import java.nio.charset.StandardCharsets;
  22. import java.util.ArrayList;
  23. import java.util.Arrays;
  24. import java.util.Collections;
  25. import java.util.List;
  26. import java.util.Optional;
  27. import java.util.stream.IntStream;
  28. import org.apache.commons.lang.RandomStringUtils;
  29. import org.junit.Before;
  30. import org.junit.Rule;
  31. import org.junit.Test;
  32. import org.mockito.internal.util.collections.Sets;
  33. import org.sonar.api.utils.System2;
  34. import org.sonar.db.DbTester;
  35. import org.sonar.db.component.BranchType;
  36. import org.sonar.db.component.ComponentDto;
  37. import org.sonar.db.metric.MetricDto;
  38. import org.sonar.db.organization.OrganizationDto;
  39. import static java.util.Arrays.asList;
  40. import static java.util.Collections.emptyList;
  41. import static java.util.Collections.singleton;
  42. import static java.util.Collections.singletonList;
  43. import static org.assertj.core.api.Assertions.assertThat;
  44. import static org.assertj.core.groups.Tuple.tuple;
  45. import static org.sonar.api.measures.Metric.ValueType.INT;
  46. import static org.sonar.db.component.ComponentTesting.newFileDto;
  47. import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto;
  48. import static org.sonar.db.measure.MeasureTesting.newLiveMeasure;
  49. public class LiveMeasureDaoTest {
  50. @Rule
  51. public DbTester db = DbTester.create(System2.INSTANCE);
  52. private LiveMeasureDao underTest = db.getDbClient().liveMeasureDao();
  53. private MetricDto metric;
  54. @Before
  55. public void setUp() {
  56. metric = db.measures().insertMetric();
  57. }
  58. @Test
  59. public void selectByComponentUuidsAndMetricIds() {
  60. LiveMeasureDto measure1 = newLiveMeasure().setMetricId(metric.getId());
  61. LiveMeasureDto measure2 = newLiveMeasure().setMetricId(metric.getId());
  62. underTest.insert(db.getSession(), measure1);
  63. underTest.insert(db.getSession(), measure2);
  64. List<LiveMeasureDto> selected = underTest.selectByComponentUuidsAndMetricIds(db.getSession(),
  65. asList(measure1.getComponentUuid(), measure2.getComponentUuid()), singletonList(metric.getId()));
  66. assertThat(selected)
  67. .extracting(LiveMeasureDto::getComponentUuid, LiveMeasureDto::getProjectUuid, LiveMeasureDto::getMetricId, LiveMeasureDto::getValue, LiveMeasureDto::getDataAsString)
  68. .containsExactlyInAnyOrder(
  69. tuple(measure1.getComponentUuid(), measure1.getProjectUuid(), measure1.getMetricId(), measure1.getValue(), measure1.getDataAsString()),
  70. tuple(measure2.getComponentUuid(), measure2.getProjectUuid(), measure2.getMetricId(), measure2.getValue(), measure2.getDataAsString()));
  71. assertThat(underTest.selectByComponentUuidsAndMetricIds(db.getSession(), emptyList(), singletonList(metric.getId()))).isEmpty();
  72. assertThat(underTest.selectByComponentUuidsAndMetricIds(db.getSession(), singletonList(measure1.getComponentUuid()), emptyList())).isEmpty();
  73. }
  74. @Test
  75. public void selectByComponentUuidsAndMetricIds_returns_empty_list_if_metric_does_not_match() {
  76. LiveMeasureDto measure = newLiveMeasure().setMetricId(metric.getId());
  77. underTest.insert(db.getSession(), measure);
  78. int otherMetricId = metric.getId() + 100;
  79. List<LiveMeasureDto> selected = underTest.selectByComponentUuidsAndMetricIds(db.getSession(), singletonList(measure.getComponentUuid()), singletonList(otherMetricId));
  80. assertThat(selected).isEmpty();
  81. }
  82. @Test
  83. public void selectByComponentUuidsAndMetricIds_returns_empty_list_if_component_does_not_match() {
  84. LiveMeasureDto measure = newLiveMeasure();
  85. underTest.insert(db.getSession(), measure);
  86. List<LiveMeasureDto> selected = underTest.selectByComponentUuidsAndMetricIds(db.getSession(), singletonList("_missing_"), singletonList(measure.getMetricId()));
  87. assertThat(selected).isEmpty();
  88. }
  89. @Test
  90. public void selectByComponentUuidsAndMetricKeys() {
  91. LiveMeasureDto measure1 = newLiveMeasure().setMetricId(metric.getId());
  92. LiveMeasureDto measure2 = newLiveMeasure().setMetricId(metric.getId());
  93. underTest.insert(db.getSession(), measure1);
  94. underTest.insert(db.getSession(), measure2);
  95. List<LiveMeasureDto> selected = underTest.selectByComponentUuidsAndMetricKeys(db.getSession(), asList(measure1.getComponentUuid(), measure2.getComponentUuid()),
  96. singletonList(metric.getKey()));
  97. assertThat(selected)
  98. .extracting(LiveMeasureDto::getComponentUuid, LiveMeasureDto::getProjectUuid, LiveMeasureDto::getMetricId, LiveMeasureDto::getValue, LiveMeasureDto::getDataAsString)
  99. .containsExactlyInAnyOrder(
  100. tuple(measure1.getComponentUuid(), measure1.getProjectUuid(), measure1.getMetricId(), measure1.getValue(), measure1.getDataAsString()),
  101. tuple(measure2.getComponentUuid(), measure2.getProjectUuid(), measure2.getMetricId(), measure2.getValue(), measure2.getDataAsString()));
  102. assertThat(underTest.selectByComponentUuidsAndMetricKeys(db.getSession(), emptyList(), singletonList(metric.getKey()))).isEmpty();
  103. assertThat(underTest.selectByComponentUuidsAndMetricKeys(db.getSession(), singletonList(measure1.getComponentUuid()), emptyList())).isEmpty();
  104. }
  105. @Test
  106. public void selectByComponentUuidsAndMetricKeys_returns_empty_list_if_metric_does_not_match() {
  107. LiveMeasureDto measure = newLiveMeasure().setMetricId(metric.getId());
  108. underTest.insert(db.getSession(), measure);
  109. List<LiveMeasureDto> selected = underTest.selectByComponentUuidsAndMetricKeys(db.getSession(), singletonList(measure.getComponentUuid()), singletonList("_other_"));
  110. assertThat(selected).isEmpty();
  111. }
  112. @Test
  113. public void selectByComponentUuidsAndMetricKeys_returns_empty_list_if_component_does_not_match() {
  114. LiveMeasureDto measure = newLiveMeasure().setMetricId(metric.getId());
  115. underTest.insert(db.getSession(), measure);
  116. List<LiveMeasureDto> selected = underTest.selectByComponentUuidsAndMetricKeys(db.getSession(), singletonList("_missing_"), singletonList(metric.getKey()));
  117. assertThat(selected).isEmpty();
  118. }
  119. @Test
  120. public void selectByComponentUuidAndMetricKey() {
  121. LiveMeasureDto measure = newLiveMeasure().setMetricId(metric.getId());
  122. underTest.insert(db.getSession(), measure);
  123. Optional<LiveMeasureDto> selected = underTest.selectByComponentUuidAndMetricKey(db.getSession(), measure.getComponentUuid(), metric.getKey());
  124. assertThat(selected).isNotEmpty();
  125. assertThat(selected.get()).isEqualToComparingFieldByField(measure);
  126. }
  127. @Test
  128. public void selectByComponentUuidAndMetricKey_return_empty_if_component_does_not_match() {
  129. LiveMeasureDto measure = newLiveMeasure().setMetricId(metric.getId());
  130. underTest.insert(db.getSession(), measure);
  131. assertThat(underTest.selectByComponentUuidAndMetricKey(db.getSession(), "_missing_", metric.getKey())).isEmpty();
  132. }
  133. @Test
  134. public void selectByComponentUuidAndMetricKey_return_empty_if_metric_does_not_match() {
  135. LiveMeasureDto measure = newLiveMeasure().setMetricId(metric.getId());
  136. underTest.insert(db.getSession(), measure);
  137. assertThat(underTest.selectByComponentUuidAndMetricKey(db.getSession(), measure.getComponentUuid(), "_missing_")).isEmpty();
  138. }
  139. @Test
  140. public void selectMeasure() {
  141. MetricDto metric = db.measures().insertMetric();
  142. LiveMeasureDto stored = newLiveMeasure().setMetricId(metric.getId());
  143. underTest.insert(db.getSession(), stored);
  144. // metric exists but not component
  145. assertThat(underTest.selectMeasure(db.getSession(), "_missing_", metric.getKey())).isEmpty();
  146. // component exists but not metric
  147. assertThat(underTest.selectMeasure(db.getSession(), stored.getComponentUuid(), "_missing_")).isEmpty();
  148. // component and metric don't match
  149. assertThat(underTest.selectMeasure(db.getSession(), "_missing_", "_missing_")).isEmpty();
  150. // matches
  151. assertThat(underTest.selectMeasure(db.getSession(), stored.getComponentUuid(), metric.getKey()).get())
  152. .isEqualToComparingFieldByField(stored);
  153. }
  154. @Test
  155. public void selectTreeByQuery() {
  156. List<LiveMeasureDto> results = new ArrayList<>();
  157. MetricDto metric = db.measures().insertMetric();
  158. ComponentDto project = db.components().insertPrivateProject();
  159. ComponentDto file = db.components().insertComponent(newFileDto(project));
  160. underTest.insert(db.getSession(), newLiveMeasure(file, metric).setValue(3.14));
  161. underTest.selectTreeByQuery(db.getSession(), project,
  162. MeasureTreeQuery.builder()
  163. .setMetricIds(singleton(metric.getId()))
  164. .setStrategy(MeasureTreeQuery.Strategy.LEAVES).build(),
  165. context -> results.add(context.getResultObject()));
  166. assertThat(results).hasSize(1);
  167. LiveMeasureDto result = results.get(0);
  168. assertThat(result.getComponentUuid()).isEqualTo(file.uuid());
  169. assertThat(result.getMetricId()).isEqualTo(metric.getId());
  170. assertThat(result.getValue()).isEqualTo(3.14);
  171. }
  172. @Test
  173. public void scrollSelectByComponentUuidAndMetricKeys_for_non_empty_metric_set() {
  174. List<LiveMeasureDto> results = new ArrayList<>();
  175. MetricDto metric = db.measures().insertMetric();
  176. MetricDto metric2 = db.measures().insertMetric();
  177. ComponentDto project = db.components().insertPrivateProject();
  178. ComponentDto project2 = db.components().insertPrivateProject();
  179. underTest.insert(db.getSession(), newLiveMeasure(project, metric).setValue(3.14));
  180. underTest.insert(db.getSession(), newLiveMeasure(project, metric2).setValue(4.54));
  181. underTest.insert(db.getSession(), newLiveMeasure(project2, metric).setValue(99.99));
  182. underTest.scrollSelectByComponentUuidAndMetricKeys(db.getSession(), project.uuid(), Sets.newSet(metric.getKey(), metric2.getKey()),
  183. context -> results.add(context.getResultObject()));
  184. assertThat(results).hasSize(2);
  185. LiveMeasureDto result = results.stream().filter(lm -> lm.getMetricId() == metric.getId()).findFirst().get();
  186. assertThat(result.getComponentUuid()).isEqualTo(project.uuid());
  187. assertThat(result.getMetricId()).isEqualTo(metric.getId());
  188. assertThat(result.getValue()).isEqualTo(3.14);
  189. LiveMeasureDto result2 = results.stream().filter(lm -> lm.getMetricId() == metric2.getId()).findFirst().get();
  190. assertThat(result2.getComponentUuid()).isEqualTo(project.uuid());
  191. assertThat(result2.getMetricId()).isEqualTo(metric2.getId());
  192. assertThat(result2.getValue()).isEqualTo(4.54);
  193. }
  194. @Test
  195. public void scrollSelectByComponentUuidAndMetricKeys_for_empty_metric_set() {
  196. List<LiveMeasureDto> results = new ArrayList<>();
  197. ComponentDto project = db.components().insertPrivateProject();
  198. underTest.scrollSelectByComponentUuidAndMetricKeys(db.getSession(), project.uuid(), Sets.newSet(),
  199. context -> results.add(context.getResultObject()));
  200. assertThat(results).isEmpty();
  201. }
  202. @Test
  203. public void selectTreeByQuery_with_empty_results() {
  204. List<LiveMeasureDto> results = new ArrayList<>();
  205. underTest.selectTreeByQuery(db.getSession(), newPrivateProjectDto(db.getDefaultOrganization()),
  206. MeasureTreeQuery.builder().setStrategy(MeasureTreeQuery.Strategy.LEAVES).build(),
  207. context -> results.add(context.getResultObject()));
  208. assertThat(results).isEmpty();
  209. }
  210. @Test
  211. public void selectMeasure_map_fields() {
  212. MetricDto metric = db.measures().insertMetric();
  213. ComponentDto project = db.components().insertPrivateProject();
  214. ComponentDto file = db.components().insertComponent(newFileDto(project));
  215. underTest.insert(db.getSession(), newLiveMeasure(file, metric).setValue(3.14).setVariation(0.1).setData("text_value"));
  216. LiveMeasureDto result = underTest.selectMeasure(db.getSession(), file.uuid(), metric.getKey()).orElseThrow(() -> new IllegalArgumentException("Measure not found"));
  217. assertThat(result).as("Fail to map fields of %s", result.toString()).extracting(
  218. LiveMeasureDto::getProjectUuid, LiveMeasureDto::getComponentUuid, LiveMeasureDto::getMetricId, LiveMeasureDto::getValue, LiveMeasureDto::getVariation,
  219. LiveMeasureDto::getDataAsString, LiveMeasureDto::getTextValue)
  220. .contains(project.uuid(), file.uuid(), metric.getId(), 3.14, 0.1, "text_value", "text_value");
  221. }
  222. @Test
  223. public void countNcloc() {
  224. OrganizationDto organization = db.organizations().insert();
  225. MetricDto ncloc = db.measures().insertMetric(m -> m.setKey("ncloc").setValueType(INT.toString()));
  226. MetricDto lines = db.measures().insertMetric(m -> m.setKey("lines").setValueType(INT.toString()));
  227. ComponentDto simpleProject = db.components().insertMainBranch(organization);
  228. db.measures().insertLiveMeasure(simpleProject, ncloc, m -> m.setValue(10d));
  229. ComponentDto projectWithBiggerBranch = db.components().insertMainBranch(organization);
  230. ComponentDto bigBranch = db.components().insertProjectBranch(projectWithBiggerBranch, b -> b.setBranchType(BranchType.BRANCH));
  231. db.measures().insertLiveMeasure(projectWithBiggerBranch, ncloc, m -> m.setValue(100d));
  232. db.measures().insertLiveMeasure(bigBranch, ncloc, m -> m.setValue(200d));
  233. ComponentDto projectWithLinesButNoLoc = db.components().insertMainBranch(organization);
  234. db.measures().insertLiveMeasure(projectWithLinesButNoLoc, lines, m -> m.setValue(365d));
  235. db.measures().insertLiveMeasure(projectWithLinesButNoLoc, ncloc, m -> m.setValue(0d));
  236. SumNclocDbQuery query = SumNclocDbQuery.builder()
  237. .setOnlyPrivateProjects(false)
  238. .setOrganizationUuid(organization.getUuid())
  239. .build();
  240. long result = underTest.sumNclocOfBiggestBranch(db.getSession(), query);
  241. assertThat(result).isEqualTo(10L + 200L);
  242. }
  243. @Test
  244. public void countNcloc_empty() {
  245. db.measures().insertMetric(m -> m.setKey("ncloc").setValueType(INT.toString()));
  246. db.measures().insertMetric(m -> m.setKey("lines").setValueType(INT.toString()));
  247. SumNclocDbQuery query = SumNclocDbQuery.builder()
  248. .setOnlyPrivateProjects(false)
  249. .setOrganizationUuid(db.getDefaultOrganization().getUuid())
  250. .build();
  251. long result = underTest.sumNclocOfBiggestBranch(db.getSession(), query);
  252. assertThat(result).isEqualTo(0L);
  253. }
  254. @Test
  255. public void countNcloc_and_exclude_project() {
  256. OrganizationDto organization = db.organizations().insert();
  257. MetricDto ncloc = db.measures().insertMetric(m -> m.setKey("ncloc").setValueType(INT.toString()));
  258. ComponentDto simpleProject = db.components().insertMainBranch(organization);
  259. db.measures().insertLiveMeasure(simpleProject, ncloc, m -> m.setValue(10d));
  260. ComponentDto projectWithBiggerBranch = db.components().insertMainBranch(organization);
  261. ComponentDto bigBranch = db.components().insertProjectBranch(projectWithBiggerBranch, b -> b.setBranchType(BranchType.BRANCH));
  262. db.measures().insertLiveMeasure(projectWithBiggerBranch, ncloc, m -> m.setValue(100d));
  263. db.measures().insertLiveMeasure(bigBranch, ncloc, m -> m.setValue(200d));
  264. ComponentDto projectToExclude = db.components().insertMainBranch(organization);
  265. ComponentDto projectToExcludeBranch = db.components().insertProjectBranch(projectToExclude, b -> b.setBranchType(BranchType.BRANCH));
  266. db.measures().insertLiveMeasure(projectToExclude, ncloc, m -> m.setValue(300d));
  267. db.measures().insertLiveMeasure(projectToExcludeBranch, ncloc, m -> m.setValue(400d));
  268. SumNclocDbQuery query = SumNclocDbQuery.builder()
  269. .setOrganizationUuid(organization.getUuid())
  270. .setProjectUuidToExclude(projectToExclude.uuid())
  271. .setOnlyPrivateProjects(false)
  272. .build();
  273. long result = underTest.sumNclocOfBiggestBranch(db.getSession(), query);
  274. assertThat(result).isEqualTo(10L + 200L);
  275. }
  276. @Test
  277. public void insert_data() {
  278. byte[] data = "text_value".getBytes(StandardCharsets.UTF_8);
  279. MetricDto metric = db.measures().insertMetric();
  280. ComponentDto project = db.components().insertPrivateProject();
  281. ComponentDto file = db.components().insertComponent(newFileDto(project));
  282. LiveMeasureDto measure = newLiveMeasure(file, metric).setData(data);
  283. underTest.insert(db.getSession(), measure);
  284. LiveMeasureDto result = underTest.selectMeasure(db.getSession(), file.uuid(), metric.getKey()).orElseThrow(() -> new IllegalArgumentException("Measure not found"));
  285. assertThat(new String(result.getData(), StandardCharsets.UTF_8)).isEqualTo("text_value");
  286. assertThat(result.getDataAsString()).isEqualTo("text_value");
  287. }
  288. @Test
  289. public void insertOrUpdate() {
  290. // insert
  291. LiveMeasureDto dto = newLiveMeasure();
  292. underTest.insertOrUpdate(db.getSession(), dto);
  293. verifyPersisted(dto);
  294. verifyTableSize(1);
  295. // update
  296. dto.setValue(dto.getValue() + 1);
  297. dto.setVariation(dto.getVariation() + 10);
  298. dto.setData(dto.getDataAsString() + "_new");
  299. underTest.insertOrUpdate(db.getSession(), dto);
  300. verifyPersisted(dto);
  301. verifyTableSize(1);
  302. }
  303. @Test
  304. public void deleteByComponentUuidExcludingMetricIds() {
  305. LiveMeasureDto measure1 = newLiveMeasure().setComponentUuid("C1").setMetricId(1);
  306. LiveMeasureDto measure2 = newLiveMeasure().setComponentUuid("C1").setMetricId(2);
  307. LiveMeasureDto measure3 = newLiveMeasure().setComponentUuid("C1").setMetricId(3);
  308. LiveMeasureDto measureOtherComponent = newLiveMeasure().setComponentUuid("C2").setMetricId(3);
  309. underTest.insertOrUpdate(db.getSession(), measure1);
  310. underTest.insertOrUpdate(db.getSession(), measure2);
  311. underTest.insertOrUpdate(db.getSession(), measure3);
  312. underTest.insertOrUpdate(db.getSession(), measureOtherComponent);
  313. int count = underTest.deleteByComponentUuidExcludingMetricIds(db.getSession(), "C1", Arrays.asList(1, 2));
  314. verifyTableSize(3);
  315. verifyPersisted(measure1);
  316. verifyPersisted(measure2);
  317. verifyPersisted(measureOtherComponent);
  318. assertThat(count).isEqualTo(1);
  319. }
  320. @Test
  321. public void deleteByComponentUuidExcludingMetricIds_with_empty_metrics() {
  322. LiveMeasureDto measure1 = newLiveMeasure().setComponentUuid("C1").setMetricId(1);
  323. LiveMeasureDto measure2 = newLiveMeasure().setComponentUuid("C1").setMetricId(2);
  324. LiveMeasureDto measureOnOtherComponent = newLiveMeasure().setComponentUuid("C2").setMetricId(2);
  325. underTest.insertOrUpdate(db.getSession(), measure1);
  326. underTest.insertOrUpdate(db.getSession(), measure2);
  327. underTest.insertOrUpdate(db.getSession(), measureOnOtherComponent);
  328. int count = underTest.deleteByComponentUuidExcludingMetricIds(db.getSession(), "C1", Collections.emptyList());
  329. assertThat(count).isEqualTo(2);
  330. verifyTableSize(1);
  331. verifyPersisted(measureOnOtherComponent);
  332. }
  333. @Test
  334. public void upsert_inserts_or_updates_row() {
  335. if (!db.getDbClient().getDatabase().getDialect().supportsUpsert()) {
  336. return;
  337. }
  338. // insert
  339. LiveMeasureDto dto = newLiveMeasure();
  340. int count = underTest.upsert(db.getSession(), asList(dto));
  341. verifyPersisted(dto);
  342. verifyTableSize(1);
  343. assertThat(count).isEqualTo(1);
  344. // update
  345. dto.setValue(dto.getValue() + 1);
  346. dto.setVariation(dto.getVariation() + 10);
  347. dto.setData(dto.getDataAsString() + "_new");
  348. count = underTest.upsert(db.getSession(), asList(dto));
  349. assertThat(count).isEqualTo(1);
  350. verifyPersisted(dto);
  351. verifyTableSize(1);
  352. }
  353. @Test
  354. public void upsert_does_not_update_row_if_values_are_not_changed() {
  355. if (!db.getDbClient().getDatabase().getDialect().supportsUpsert()) {
  356. return;
  357. }
  358. LiveMeasureDto dto = newLiveMeasure();
  359. underTest.upsert(db.getSession(), asList(dto));
  360. // update
  361. int count = underTest.upsert(db.getSession(), asList(dto));
  362. assertThat(count).isEqualTo(0);
  363. verifyPersisted(dto);
  364. verifyTableSize(1);
  365. }
  366. @Test
  367. public void upsert_updates_row_if_lob_data_is_changed() {
  368. if (!db.getDbClient().getDatabase().getDialect().supportsUpsert()) {
  369. return;
  370. }
  371. LiveMeasureDto dto = newLiveMeasure().setData(RandomStringUtils.random(10_000));
  372. underTest.upsert(db.getSession(), asList(dto));
  373. // update
  374. dto.setData(RandomStringUtils.random(dto.getDataAsString().length() + 10));
  375. int count = underTest.upsert(db.getSession(), asList(dto));
  376. assertThat(count).isEqualTo(1);
  377. verifyPersisted(dto);
  378. verifyTableSize(1);
  379. }
  380. @Test
  381. public void upsert_does_not_update_row_if_lob_data_is_not_changed() {
  382. if (!db.getDbClient().getDatabase().getDialect().supportsUpsert()) {
  383. return;
  384. }
  385. LiveMeasureDto dto = newLiveMeasure().setData(RandomStringUtils.random(10_000));
  386. underTest.upsert(db.getSession(), asList(dto));
  387. // update
  388. int count = underTest.upsert(db.getSession(), asList(dto));
  389. assertThat(count).isEqualTo(0);
  390. verifyPersisted(dto);
  391. verifyTableSize(1);
  392. }
  393. @Test
  394. public void upsert_updates_row_if_lob_data_is_removed() {
  395. if (!db.getDbClient().getDatabase().getDialect().supportsUpsert()) {
  396. return;
  397. }
  398. LiveMeasureDto dto = newLiveMeasure().setData(RandomStringUtils.random(10_000));
  399. underTest.upsert(db.getSession(), asList(dto));
  400. // update
  401. dto.setData((String) null);
  402. int count = underTest.upsert(db.getSession(), asList(dto));
  403. assertThat(count).isEqualTo(1);
  404. verifyPersisted(dto);
  405. verifyTableSize(1);
  406. }
  407. @Test
  408. public void upsert_updates_row_if_variation_is_changed() {
  409. if (!db.getDbClient().getDatabase().getDialect().supportsUpsert()) {
  410. return;
  411. }
  412. LiveMeasureDto dto = newLiveMeasure().setVariation(40.0);
  413. underTest.upsert(db.getSession(), asList(dto));
  414. // update
  415. dto.setVariation(50.0);
  416. int count = underTest.upsert(db.getSession(), asList(dto));
  417. assertThat(count).isEqualTo(1);
  418. verifyPersisted(dto);
  419. verifyTableSize(1);
  420. }
  421. @Test
  422. public void upsert_updates_row_if_variation_is_removed() {
  423. if (!db.getDbClient().getDatabase().getDialect().supportsUpsert()) {
  424. return;
  425. }
  426. LiveMeasureDto dto = newLiveMeasure().setVariation(40.0);
  427. underTest.upsert(db.getSession(), asList(dto));
  428. // update
  429. dto.setVariation(null);
  430. int count = underTest.upsert(db.getSession(), asList(dto));
  431. assertThat(count).isEqualTo(1);
  432. verifyPersisted(dto);
  433. verifyTableSize(1);
  434. }
  435. @Test
  436. public void upsert_updates_row_if_variation_is_added() {
  437. if (!db.getDbClient().getDatabase().getDialect().supportsUpsert()) {
  438. return;
  439. }
  440. LiveMeasureDto dto = newLiveMeasure().setVariation(null);
  441. underTest.upsert(db.getSession(), asList(dto));
  442. // update
  443. dto.setVariation(40.0);
  444. int count = underTest.upsert(db.getSession(), asList(dto));
  445. assertThat(count).isEqualTo(1);
  446. verifyPersisted(dto);
  447. verifyTableSize(1);
  448. }
  449. @Test
  450. public void upsert_updates_row_if_value_is_changed() {
  451. if (!db.getDbClient().getDatabase().getDialect().supportsUpsert()) {
  452. return;
  453. }
  454. LiveMeasureDto dto = newLiveMeasure().setValue(40.0);
  455. underTest.upsert(db.getSession(), asList(dto));
  456. // update
  457. dto.setValue(50.0);
  458. int count = underTest.upsert(db.getSession(), asList(dto));
  459. assertThat(count).isEqualTo(1);
  460. verifyPersisted(dto);
  461. verifyTableSize(1);
  462. }
  463. @Test
  464. public void upsert_updates_row_if_value_is_removed() {
  465. if (!db.getDbClient().getDatabase().getDialect().supportsUpsert()) {
  466. return;
  467. }
  468. LiveMeasureDto dto = newLiveMeasure().setValue(40.0);
  469. underTest.upsert(db.getSession(), asList(dto));
  470. // update
  471. dto.setValue(null);
  472. int count = underTest.upsert(db.getSession(), asList(dto));
  473. assertThat(count).isEqualTo(1);
  474. verifyPersisted(dto);
  475. verifyTableSize(1);
  476. }
  477. @Test
  478. public void upsert_updates_row_if_value_is_added() {
  479. if (!db.getDbClient().getDatabase().getDialect().supportsUpsert()) {
  480. return;
  481. }
  482. LiveMeasureDto dto = newLiveMeasure().setValue(null);
  483. underTest.upsert(db.getSession(), asList(dto));
  484. // update
  485. dto.setValue(40.0);
  486. int count = underTest.upsert(db.getSession(), asList(dto));
  487. assertThat(count).isEqualTo(1);
  488. verifyPersisted(dto);
  489. verifyTableSize(1);
  490. }
  491. @Test
  492. public void upsert_multiple_rows() {
  493. if (!db.getDbClient().getDatabase().getDialect().supportsUpsert()) {
  494. return;
  495. }
  496. // insert 30
  497. List<LiveMeasureDto> inserted = new ArrayList<>();
  498. IntStream.range(0, 30).forEach(i -> inserted.add(newLiveMeasure()));
  499. int result = underTest.upsert(db.getSession(), inserted);
  500. verifyTableSize(30);
  501. assertThat(result).isEqualTo(30);
  502. // update 10 with new values, update 5 without any change and insert new 50
  503. List<LiveMeasureDto> upserted = new ArrayList<>();
  504. IntStream.range(0, 10).forEach(i -> {
  505. LiveMeasureDto d = inserted.get(i);
  506. upserted.add(d.setValue(d.getValue() + 123));
  507. });
  508. upserted.addAll(inserted.subList(10, 15));
  509. IntStream.range(0, 50).forEach(i -> upserted.add(newLiveMeasure()));
  510. result = underTest.upsert(db.getSession(), upserted);
  511. verifyTableSize(80);
  512. assertThat(result).isEqualTo(60);
  513. }
  514. private void verifyTableSize(int expectedSize) {
  515. assertThat(db.countRowsOfTable(db.getSession(), "live_measures")).isEqualTo(expectedSize);
  516. }
  517. private void verifyPersisted(LiveMeasureDto dto) {
  518. List<LiveMeasureDto> selected = underTest.selectByComponentUuidsAndMetricIds(db.getSession(), singletonList(dto.getComponentUuid()), singletonList(dto.getMetricId()));
  519. assertThat(selected).hasSize(1);
  520. assertThat(selected.get(0)).isEqualToComparingOnlyGivenFields(dto,
  521. // do not compare the field "uuid", which is used only for insert, not select
  522. "componentUuid", "projectUuid", "metricId", "value", "textValue", "data", "variation");
  523. }
  524. }