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.

MapBasedRawMeasureRepositoryTest.java 9.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2020 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.ce.task.projectanalysis.measure;
  21. import com.google.common.collect.ImmutableList;
  22. import com.tngtech.java.junit.dataprovider.DataProvider;
  23. import com.tngtech.java.junit.dataprovider.DataProviderRunner;
  24. import com.tngtech.java.junit.dataprovider.UseDataProvider;
  25. import java.util.List;
  26. import java.util.Optional;
  27. import org.junit.Before;
  28. import org.junit.Rule;
  29. import org.junit.Test;
  30. import org.junit.rules.ExpectedException;
  31. import org.junit.runner.RunWith;
  32. import org.sonar.api.utils.System2;
  33. import org.sonar.ce.task.projectanalysis.batch.BatchReportReader;
  34. import org.sonar.ce.task.projectanalysis.component.Component;
  35. import org.sonar.ce.task.projectanalysis.component.ReportComponent;
  36. import org.sonar.ce.task.projectanalysis.metric.Metric;
  37. import org.sonar.ce.task.projectanalysis.metric.MetricImpl;
  38. import org.sonar.ce.task.projectanalysis.metric.MetricRepository;
  39. import org.sonar.ce.task.projectanalysis.metric.ReportMetricValidator;
  40. import org.sonar.db.DbClient;
  41. import org.sonar.db.DbTester;
  42. import static java.lang.String.format;
  43. import static org.assertj.core.api.Assertions.assertThat;
  44. import static org.junit.Assert.fail;
  45. import static org.mockito.Mockito.mock;
  46. import static org.mockito.Mockito.verifyNoMoreInteractions;
  47. import static org.mockito.Mockito.when;
  48. @RunWith(DataProviderRunner.class)
  49. public class MapBasedRawMeasureRepositoryTest {
  50. @Rule
  51. public DbTester dbTester = DbTester.create(System2.INSTANCE);
  52. @Rule
  53. public ExpectedException expectedException = ExpectedException.none();
  54. private static final String FILE_COMPONENT_KEY = "file cpt key";
  55. private static final ReportComponent FILE_COMPONENT = ReportComponent.builder(Component.Type.FILE, 1)
  56. .setKey(FILE_COMPONENT_KEY)
  57. .setUuid("1")
  58. .build();
  59. private static final ReportComponent OTHER_COMPONENT = ReportComponent.builder(Component.Type.FILE, 2)
  60. .setKey("some other key")
  61. .setUuid("2")
  62. .build();
  63. private static final String METRIC_KEY_1 = "metric 1";
  64. private static final String METRIC_KEY_2 = "metric 2";
  65. private final Metric metric1 = mock(Metric.class);
  66. private final Metric metric2 = mock(Metric.class);
  67. private static final Measure SOME_MEASURE = Measure.newMeasureBuilder().create("some value");
  68. private ReportMetricValidator reportMetricValidator = mock(ReportMetricValidator.class);
  69. private MetricRepository metricRepository = mock(MetricRepository.class);
  70. private MapBasedRawMeasureRepository<Integer> underTest = new MapBasedRawMeasureRepository<>(component -> component.getReportAttributes().getRef());
  71. private DbClient mockedDbClient = mock(DbClient.class);
  72. private BatchReportReader mockBatchReportReader = mock(BatchReportReader.class);
  73. private MeasureRepositoryImpl underTestWithMock = new MeasureRepositoryImpl(mockedDbClient, mockBatchReportReader, metricRepository, reportMetricValidator);
  74. @Before
  75. public void setUp() {
  76. when(metric1.getKey()).thenReturn(METRIC_KEY_1);
  77. when(metric1.getType()).thenReturn(Metric.MetricType.STRING);
  78. when(metric2.getKey()).thenReturn(METRIC_KEY_2);
  79. when(metric2.getType()).thenReturn(Metric.MetricType.STRING);
  80. // references to metrics are consistent with DB by design
  81. when(metricRepository.getByKey(METRIC_KEY_1)).thenReturn(metric1);
  82. when(metricRepository.getByKey(METRIC_KEY_2)).thenReturn(metric2);
  83. }
  84. @Test(expected = NullPointerException.class)
  85. public void add_throws_NPE_if_Component_argument_is_null() {
  86. underTest.add(null, metric1, SOME_MEASURE);
  87. }
  88. @Test(expected = NullPointerException.class)
  89. public void add_throws_NPE_if_Component_metric_is_null() {
  90. underTest.add(FILE_COMPONENT, null, SOME_MEASURE);
  91. }
  92. @Test(expected = NullPointerException.class)
  93. public void add_throws_NPE_if_Component_measure_is_null() {
  94. underTest.add(FILE_COMPONENT, metric1, null);
  95. }
  96. @Test(expected = UnsupportedOperationException.class)
  97. public void add_throws_UOE_if_measure_already_exists() {
  98. underTest.add(FILE_COMPONENT, metric1, SOME_MEASURE);
  99. underTest.add(FILE_COMPONENT, metric1, SOME_MEASURE);
  100. }
  101. @Test(expected = NullPointerException.class)
  102. public void update_throws_NPE_if_Component_argument_is_null() {
  103. underTest.update(null, metric1, SOME_MEASURE);
  104. }
  105. @Test(expected = NullPointerException.class)
  106. public void update_throws_NPE_if_Component_metric_is_null() {
  107. underTest.update(FILE_COMPONENT, null, SOME_MEASURE);
  108. }
  109. @Test(expected = NullPointerException.class)
  110. public void update_throws_NPE_if_Component_measure_is_null() {
  111. underTest.update(FILE_COMPONENT, metric1, null);
  112. }
  113. @Test(expected = UnsupportedOperationException.class)
  114. public void update_throws_UOE_if_measure_does_not_exists() {
  115. underTest.update(FILE_COMPONENT, metric1, SOME_MEASURE);
  116. }
  117. private static final List<Measure> MEASURES = ImmutableList.of(
  118. Measure.newMeasureBuilder().create(1),
  119. Measure.newMeasureBuilder().create(1l),
  120. Measure.newMeasureBuilder().create(1d, 1),
  121. Measure.newMeasureBuilder().create(true),
  122. Measure.newMeasureBuilder().create(false),
  123. Measure.newMeasureBuilder().create("sds"),
  124. Measure.newMeasureBuilder().create(Measure.Level.OK),
  125. Measure.newMeasureBuilder().createNoValue());
  126. @DataProvider
  127. public static Object[][] measures() {
  128. return MEASURES.stream()
  129. .map(c -> new Measure[] {c})
  130. .toArray(i -> new Object[i][]);
  131. }
  132. @Test
  133. public void add_accepts_NO_VALUE_as_measure_arg() {
  134. for (Metric.MetricType metricType : Metric.MetricType.values()) {
  135. underTest.add(FILE_COMPONENT, new MetricImpl("1", "key" + metricType, "name" + metricType, metricType), Measure.newMeasureBuilder().createNoValue());
  136. }
  137. }
  138. @Test
  139. @UseDataProvider("measures")
  140. public void update_throws_IAE_if_valueType_of_Measure_is_not_the_same_as_the_Metric_valueType_unless_NO_VALUE(Measure measure) {
  141. for (Metric.MetricType metricType : Metric.MetricType.values()) {
  142. if (metricType.getValueType() == measure.getValueType() || measure.getValueType() == Measure.ValueType.NO_VALUE) {
  143. continue;
  144. }
  145. try {
  146. final MetricImpl metric = new MetricImpl("1", "key" + metricType, "name" + metricType, metricType);
  147. underTest.add(FILE_COMPONENT, metric, getSomeMeasureByValueType(metricType));
  148. underTest.update(FILE_COMPONENT, metric, measure);
  149. fail("An IllegalArgumentException should have been raised");
  150. } catch (IllegalArgumentException e) {
  151. assertThat(e).hasMessage(format(
  152. "Measure's ValueType (%s) is not consistent with the Metric's ValueType (%s)",
  153. measure.getValueType(), metricType.getValueType()));
  154. }
  155. }
  156. }
  157. @Test
  158. public void update_accepts_NO_VALUE_as_measure_arg() {
  159. for (Metric.MetricType metricType : Metric.MetricType.values()) {
  160. MetricImpl metric = new MetricImpl("1", "key" + metricType, "name" + metricType, metricType);
  161. underTest.add(FILE_COMPONENT, metric, getSomeMeasureByValueType(metricType));
  162. underTest.update(FILE_COMPONENT, metric, Measure.newMeasureBuilder().createNoValue());
  163. }
  164. }
  165. private Measure getSomeMeasureByValueType(final Metric.MetricType metricType) {
  166. return MEASURES.stream()
  167. .filter(measure -> measure.getValueType() == metricType.getValueType())
  168. .findFirst().get();
  169. }
  170. @Test
  171. public void update_supports_updating_to_the_same_value() {
  172. underTest.add(FILE_COMPONENT, metric1, SOME_MEASURE);
  173. underTest.update(FILE_COMPONENT, metric1, SOME_MEASURE);
  174. }
  175. @Test
  176. public void update_updates_the_stored_value() {
  177. Measure newMeasure = Measure.updatedMeasureBuilder(SOME_MEASURE).create();
  178. underTest.add(FILE_COMPONENT, metric1, SOME_MEASURE);
  179. underTest.update(FILE_COMPONENT, metric1, newMeasure);
  180. assertThat(underTest.getRawMeasure(FILE_COMPONENT, metric1).get()).isSameAs(newMeasure);
  181. }
  182. @Test
  183. public void getRawMeasure_throws_NPE_without_reading_batch_report_if_component_arg_is_null() {
  184. try {
  185. underTestWithMock.getRawMeasure(null, metric1);
  186. fail("an NPE should have been raised");
  187. } catch (NullPointerException e) {
  188. verifyNoMoreInteractions(mockBatchReportReader);
  189. }
  190. }
  191. @Test
  192. public void getRawMeasure_throws_NPE_without_reading_batch_report_if_metric_arg_is_null() {
  193. try {
  194. underTestWithMock.getRawMeasure(FILE_COMPONENT, null);
  195. fail("an NPE should have been raised");
  196. } catch (NullPointerException e) {
  197. verifyNoMoreInteractions(mockBatchReportReader);
  198. }
  199. }
  200. @Test
  201. public void getRawMeasure_returns_measure_added_through_add_method() {
  202. underTest.add(FILE_COMPONENT, metric1, SOME_MEASURE);
  203. Optional<Measure> res = underTest.getRawMeasure(FILE_COMPONENT, metric1);
  204. assertThat(res).isPresent();
  205. assertThat(res.get()).isSameAs(SOME_MEASURE);
  206. // make sure we really match on the specified component and metric
  207. assertThat(underTest.getRawMeasure(OTHER_COMPONENT, metric1)).isNotPresent();
  208. assertThat(underTest.getRawMeasure(FILE_COMPONENT, metric2)).isNotPresent();
  209. }
  210. }