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.

ExecuteVisitorsStepTest.java 8.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  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.ce.task.projectanalysis.step;
  21. import java.util.List;
  22. import org.junit.Before;
  23. import org.junit.Rule;
  24. import org.junit.Test;
  25. import org.sonar.api.utils.log.LogTester;
  26. import org.sonar.api.utils.log.LoggerLevel;
  27. import org.sonar.ce.task.ChangeLogLevel;
  28. import org.sonar.ce.task.projectanalysis.component.Component;
  29. import org.sonar.ce.task.projectanalysis.component.ComponentVisitor;
  30. import org.sonar.ce.task.projectanalysis.component.CrawlerDepthLimit;
  31. import org.sonar.ce.task.projectanalysis.component.PathAwareVisitorAdapter;
  32. import org.sonar.ce.task.projectanalysis.component.TreeRootHolderRule;
  33. import org.sonar.ce.task.projectanalysis.component.TypeAwareVisitorAdapter;
  34. import org.sonar.ce.task.projectanalysis.measure.MeasureRepositoryRule;
  35. import org.sonar.ce.task.projectanalysis.metric.Metric;
  36. import org.sonar.ce.task.projectanalysis.metric.MetricImpl;
  37. import org.sonar.ce.task.projectanalysis.metric.MetricRepositoryRule;
  38. import org.sonar.ce.task.step.TestComputationStepContext;
  39. import static java.util.Arrays.asList;
  40. import static java.util.Collections.singletonList;
  41. import static org.assertj.core.api.Assertions.assertThat;
  42. import static org.sonar.api.measures.CoreMetrics.NCLOC;
  43. import static org.sonar.api.measures.CoreMetrics.NCLOC_KEY;
  44. import static org.sonar.ce.task.projectanalysis.component.Component.Type.DIRECTORY;
  45. import static org.sonar.ce.task.projectanalysis.component.Component.Type.FILE;
  46. import static org.sonar.ce.task.projectanalysis.component.Component.Type.PROJECT;
  47. import static org.sonar.ce.task.projectanalysis.component.ReportComponent.builder;
  48. import static org.sonar.ce.task.projectanalysis.measure.Measure.newMeasureBuilder;
  49. public class ExecuteVisitorsStepTest {
  50. private static final String TEST_METRIC_KEY = "test";
  51. private static final int ROOT_REF = 1;
  52. private static final int DIRECTORY_REF = 123;
  53. private static final int FILE_1_REF = 1231;
  54. private static final int FILE_2_REF = 1232;
  55. @Rule
  56. public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
  57. @Rule
  58. public MetricRepositoryRule metricRepository = new MetricRepositoryRule()
  59. .add("1", NCLOC)
  60. .add(new MetricImpl("2", TEST_METRIC_KEY, "name", Metric.MetricType.INT));
  61. @Rule
  62. public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository);
  63. @Rule
  64. public LogTester logTester = new LogTester();
  65. @Before
  66. public void setUp() throws Exception {
  67. treeRootHolder.setRoot(
  68. builder(PROJECT, ROOT_REF).setKey("project")
  69. .addChildren(
  70. builder(DIRECTORY, DIRECTORY_REF).setKey("directory")
  71. .addChildren(
  72. builder(FILE, FILE_1_REF).setKey("file1").build(),
  73. builder(FILE, FILE_2_REF).setKey("file2").build())
  74. .build())
  75. .build());
  76. }
  77. @Test
  78. public void execute_with_type_aware_visitor() {
  79. ExecuteVisitorsStep underStep = new ExecuteVisitorsStep(treeRootHolder, singletonList(new TestTypeAwareVisitor()));
  80. measureRepository.addRawMeasure(FILE_1_REF, NCLOC_KEY, newMeasureBuilder().create(1));
  81. measureRepository.addRawMeasure(FILE_2_REF, NCLOC_KEY, newMeasureBuilder().create(2));
  82. measureRepository.addRawMeasure(DIRECTORY_REF, NCLOC_KEY, newMeasureBuilder().create(3));
  83. measureRepository.addRawMeasure(ROOT_REF, NCLOC_KEY, newMeasureBuilder().create(3));
  84. underStep.execute(new TestComputationStepContext());
  85. assertThat(measureRepository.getAddedRawMeasure(FILE_1_REF, TEST_METRIC_KEY).get().getIntValue()).isEqualTo(2);
  86. assertThat(measureRepository.getAddedRawMeasure(FILE_2_REF, TEST_METRIC_KEY).get().getIntValue()).isEqualTo(3);
  87. assertThat(measureRepository.getAddedRawMeasure(DIRECTORY_REF, TEST_METRIC_KEY).get().getIntValue()).isEqualTo(4);
  88. assertThat(measureRepository.getAddedRawMeasure(ROOT_REF, TEST_METRIC_KEY).get().getIntValue()).isEqualTo(4);
  89. }
  90. @Test
  91. public void execute_with_path_aware_visitor() {
  92. ExecuteVisitorsStep underTest = new ExecuteVisitorsStep(treeRootHolder, singletonList(new TestPathAwareVisitor()));
  93. measureRepository.addRawMeasure(FILE_1_REF, NCLOC_KEY, newMeasureBuilder().create(1));
  94. measureRepository.addRawMeasure(FILE_2_REF, NCLOC_KEY, newMeasureBuilder().create(1));
  95. underTest.execute(new TestComputationStepContext());
  96. assertThat(measureRepository.getAddedRawMeasure(FILE_1_REF, TEST_METRIC_KEY).get().getIntValue()).isEqualTo(1);
  97. assertThat(measureRepository.getAddedRawMeasure(FILE_2_REF, TEST_METRIC_KEY).get().getIntValue()).isEqualTo(1);
  98. assertThat(measureRepository.getAddedRawMeasure(DIRECTORY_REF, TEST_METRIC_KEY).get().getIntValue()).isEqualTo(2);
  99. assertThat(measureRepository.getAddedRawMeasure(ROOT_REF, TEST_METRIC_KEY).get().getIntValue()).isEqualTo(2);
  100. }
  101. @Test
  102. public void execute_logs_at_info_level_all_execution_duration_of_all_visitors() {
  103. try (ChangeLogLevel executor = new ChangeLogLevel(ExecuteVisitorsStep.class, LoggerLevel.DEBUG);
  104. ChangeLogLevel step1 = new ChangeLogLevel(VisitorA.class, LoggerLevel.DEBUG);
  105. ChangeLogLevel step2 = new ChangeLogLevel(VisitorB.class, LoggerLevel.DEBUG);
  106. ChangeLogLevel step3 = new ChangeLogLevel(VisitorB.class, LoggerLevel.DEBUG)) {
  107. ExecuteVisitorsStep underTest = new ExecuteVisitorsStep(
  108. treeRootHolder,
  109. asList(new VisitorA(), new VisitorB(), new VisitorC()));
  110. underTest.execute(new TestComputationStepContext());
  111. List<String> logs = logTester.logs(LoggerLevel.DEBUG);
  112. assertThat(logs).hasSize(4);
  113. assertThat(logs.get(0)).isEqualTo(" Execution time for each component visitor:");
  114. assertThat(logs.get(1)).startsWith(" - VisitorA | time=");
  115. assertThat(logs.get(2)).startsWith(" - VisitorB | time=");
  116. assertThat(logs.get(3)).startsWith(" - VisitorC | time=");
  117. }
  118. }
  119. private static class VisitorA extends TypeAwareVisitorAdapter {
  120. VisitorA() {
  121. super(CrawlerDepthLimit.PROJECT, Order.PRE_ORDER);
  122. }
  123. }
  124. private static class VisitorB extends TypeAwareVisitorAdapter {
  125. VisitorB() {
  126. super(CrawlerDepthLimit.PROJECT, Order.PRE_ORDER);
  127. }
  128. }
  129. private static class VisitorC extends TypeAwareVisitorAdapter {
  130. VisitorC() {
  131. super(CrawlerDepthLimit.PROJECT, Order.PRE_ORDER);
  132. }
  133. }
  134. private class TestTypeAwareVisitor extends TypeAwareVisitorAdapter {
  135. TestTypeAwareVisitor() {
  136. super(CrawlerDepthLimit.FILE, ComponentVisitor.Order.POST_ORDER);
  137. }
  138. @Override
  139. public void visitAny(Component any) {
  140. int ncloc = measureRepository.getRawMeasure(any, metricRepository.getByKey(NCLOC_KEY)).get().getIntValue();
  141. measureRepository.add(any, metricRepository.getByKey(TEST_METRIC_KEY), newMeasureBuilder().create(ncloc + 1));
  142. }
  143. }
  144. private class TestPathAwareVisitor extends PathAwareVisitorAdapter<Counter> {
  145. TestPathAwareVisitor() {
  146. super(CrawlerDepthLimit.FILE, ComponentVisitor.Order.POST_ORDER, new SimpleStackElementFactory<Counter>() {
  147. @Override
  148. public Counter createForAny(Component component) {
  149. return new Counter();
  150. }
  151. });
  152. }
  153. @Override
  154. public void visitProject(Component project, Path<Counter> path) {
  155. computeAndSaveMeasures(project, path);
  156. }
  157. @Override
  158. public void visitDirectory(Component directory, Path<Counter> path) {
  159. computeAndSaveMeasures(directory, path);
  160. }
  161. @Override
  162. public void visitFile(Component file, Path<Counter> path) {
  163. int ncloc = measureRepository.getRawMeasure(file, metricRepository.getByKey(NCLOC_KEY)).get().getIntValue();
  164. path.current().add(ncloc);
  165. computeAndSaveMeasures(file, path);
  166. }
  167. private void computeAndSaveMeasures(Component component, Path<Counter> path) {
  168. measureRepository.add(component, metricRepository.getByKey(TEST_METRIC_KEY), newMeasureBuilder().create(path.current().getValue()));
  169. increaseParentValue(path);
  170. }
  171. private void increaseParentValue(Path<Counter> path) {
  172. if (!path.isRoot()) {
  173. path.parent().add(path.current().getValue());
  174. }
  175. }
  176. }
  177. public static class Counter {
  178. private int value = 0;
  179. public void add(int value) {
  180. this.value += value;
  181. }
  182. public int getValue() {
  183. return value;
  184. }
  185. }
  186. }