3 * Copyright (C) 2009-2016 SonarSource SA
4 * mailto:contact AT sonarsource DOT com
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.
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.
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.
20 package org.sonar.server.computation.task.projectanalysis.component;
22 import com.google.common.base.Optional;
23 import com.google.common.base.Supplier;
24 import java.util.Arrays;
25 import java.util.EnumSet;
26 import java.util.HashMap;
28 import java.util.function.Function;
29 import org.junit.Rule;
30 import org.junit.Test;
31 import org.junit.rules.ExternalResource;
32 import org.sonar.db.component.ComponentDto;
33 import org.sonar.scanner.protocol.output.ScannerReport;
35 import static com.google.common.base.Preconditions.checkArgument;
36 import static com.google.common.base.Preconditions.checkNotNull;
37 import static org.assertj.core.api.Assertions.assertThat;
38 import static org.assertj.core.api.Assertions.fail;
39 import static org.sonar.scanner.protocol.output.ScannerReport.Component.newBuilder;
40 import static org.sonar.scanner.protocol.output.ScannerReport.Component.ComponentType.DIRECTORY;
41 import static org.sonar.scanner.protocol.output.ScannerReport.Component.ComponentType.FILE;
42 import static org.sonar.scanner.protocol.output.ScannerReport.Component.ComponentType.MODULE;
43 import static org.sonar.scanner.protocol.output.ScannerReport.Component.ComponentType.PROJECT;
44 import static org.sonar.scanner.protocol.output.ScannerReport.Component.ComponentType.UNRECOGNIZED;
45 import static org.sonar.scanner.protocol.output.ScannerReport.Component.ComponentType.UNSET;
46 import static org.sonar.server.computation.task.projectanalysis.component.ComponentRootBuilder.createFileAttributes;
47 import static org.sonar.server.computation.task.projectanalysis.component.ComponentRootBuilder.createReportAttributes;
48 import static org.sonar.server.computation.task.projectanalysis.component.ComponentVisitor.Order.PRE_ORDER;
50 public class ComponentRootBuilderTest {
52 private static final Function<String, String> SIMPLE_UUID_GENERATOR = (componentKey) -> componentKey + "_uuid";
53 private static final String NO_BRANCH = null;
54 private static final String PROJECT_KEY = "this is the key";
55 private static final String MODULE_KEY = "module key";
56 private static final String DIRECTORY_PATH = "directory path";
57 private static final String DIRECTORY_KEY = MODULE_KEY + ":" + DIRECTORY_PATH;
58 private static final String FILE_PATH = "file path";
59 private static final String FILE_KEY = MODULE_KEY + ":" + FILE_PATH;
60 private static final ComponentDto PROJECT_DTO = new ComponentDto().setName("name in db");
61 private static final Supplier<Optional<ComponentDto>> NO_COMPONENT_DTO_FOR_PROJECT = Optional::absent;
62 private static final Supplier<Optional<ComponentDto>> COMPONENT_DTO_FOR_PROJECT = () -> Optional.of(PROJECT_DTO);
63 private static final EnumSet<ScannerReport.Component.ComponentType> REPORT_TYPES = EnumSet.of(
64 PROJECT, MODULE, DIRECTORY, FILE);
67 public ScannerComponentProvider scannerComponentProvider = new ScannerComponentProvider();
69 private ComponentRootBuilder underTest = new ComponentRootBuilder(NO_BRANCH, SIMPLE_UUID_GENERATOR, scannerComponentProvider, NO_COMPONENT_DTO_FOR_PROJECT);
72 public void build_throws_IAE_for_all_types_but_PROJECT_MODULE_DIRECTORY_FILE() {
73 Arrays.stream(ScannerReport.Component.ComponentType.values())
74 .filter((type) -> type != UNRECOGNIZED)
75 .filter((type) -> !REPORT_TYPES.contains(type))
78 ScannerReport.Component component = newBuilder().setType(type).build();
80 underTest.build(component, "don't care");
81 fail("Should have thrown a IllegalArgumentException");
82 } catch (IllegalArgumentException e) {
83 assertThat(e).hasMessage("Unsupported component type '" + type + "'");
89 public void name_of_project_is_name_in_Scanner_Component_when_set() {
90 String expected = "the name";
91 Component root = underTest.build(newBuilder().setType(PROJECT).setName(expected).build(), PROJECT_KEY);
92 assertThat(root.getName()).isEqualTo(expected);
96 public void name_of_project_is_name_in_Scanner_Component_when_set_even_if_there_is_a_ComponentDto() {
97 String expected = "the name";
98 Component root = new ComponentRootBuilder(NO_BRANCH, SIMPLE_UUID_GENERATOR, scannerComponentProvider, COMPONENT_DTO_FOR_PROJECT)
99 .build(newBuilder().setType(PROJECT).setName(expected).build(), PROJECT_KEY);
100 assertThat(root.getName()).isEqualTo(expected);
104 public void name_of_project_is_specified_key_when_name_is_unset_in_Scanner_Component_and_there_is_no_ComponentDto() {
105 Component root = underTest.build(newBuilder().setType(PROJECT).build(), PROJECT_KEY);
106 assertThat(root.getName()).isEqualTo(PROJECT_KEY);
110 public void name_of_project_is_specified_key_when_name_is_empty_in_Scanner_Component_and_there_is_no_ComponentDto() {
111 Component root = underTest.build(newBuilder().setType(PROJECT).setName("").build(), PROJECT_KEY);
113 assertThat(root.getName()).isEqualTo(PROJECT_KEY);
117 public void name_of_project_is_name_of_ComponentDto_when_name_is_unset_in_Scanner_Component_and_there_is_a_ComponentDto() {
118 Component root = new ComponentRootBuilder(NO_BRANCH, SIMPLE_UUID_GENERATOR, scannerComponentProvider, COMPONENT_DTO_FOR_PROJECT)
119 .build(newBuilder().setType(PROJECT).build(), PROJECT_KEY);
121 assertThat(root.getName()).isEqualTo(PROJECT_DTO.name());
125 public void name_of_project_is_name_of_ComponentDto_when_name_is_empty_in_Scanner_Component_and_there_is_a_ComponentDto() {
126 Component root = new ComponentRootBuilder(NO_BRANCH, SIMPLE_UUID_GENERATOR, scannerComponentProvider, COMPONENT_DTO_FOR_PROJECT)
127 .build(newBuilder().setType(PROJECT).setName("").build(), PROJECT_KEY);
129 assertThat(root.getName()).isEqualTo(PROJECT_DTO.name());
133 public void name_of_module_directory_and_file_contains_branch_when_non_empty() {
134 ScannerReport.Component project = newBuilder().setType(PROJECT).setRef(1).addChildRef(2).build();
135 scannerComponentProvider.add(newBuilder().setRef(2).setType(MODULE).setKey(MODULE_KEY).addChildRef(3));
136 scannerComponentProvider.add(newBuilder().setRef(3).setType(DIRECTORY).setPath(DIRECTORY_PATH).addChildRef(4));
137 scannerComponentProvider.add(newBuilder().setRef(4).setType(FILE).setPath(FILE_PATH));
139 String branch = "BRANCH";
140 ComponentRootBuilder builder = new ComponentRootBuilder(branch, SIMPLE_UUID_GENERATOR, scannerComponentProvider, NO_COMPONENT_DTO_FOR_PROJECT);
142 Component root = builder.build(project, PROJECT_KEY);
143 assertThat(root.getKey()).isEqualTo(PROJECT_KEY);
144 assertThat(root.getChildren()).hasSize(1);
145 Component module = root.getChildren().iterator().next();
146 assertThat(module.getKey()).isEqualTo(MODULE_KEY + ":" + branch);
147 assertThat(module.getChildren()).hasSize(1);
148 Component directory = module.getChildren().iterator().next();
149 assertThat(directory.getKey()).isEqualTo(module.getKey() + ":" + DIRECTORY_PATH);
150 assertThat(directory.getChildren()).hasSize(1);
151 Component file = directory.getChildren().iterator().next();
152 assertThat(file.getKey()).isEqualTo(module.getKey() + ":" + FILE_PATH);
153 assertThat(file.getChildren()).isEmpty();
157 public void name_of_module_directory_and_file_is_key_of_Scanner_Component_when_name_is_unset() {
158 ScannerReport.Component project = newBuilder().setType(PROJECT).setRef(1).addChildRef(2).build();
159 scannerComponentProvider.add(newBuilder().setRef(2).setType(MODULE).setKey(MODULE_KEY).addChildRef(3));
160 scannerComponentProvider.add(newBuilder().setRef(3).setType(DIRECTORY).setPath(DIRECTORY_PATH).addChildRef(4));
161 scannerComponentProvider.add(newBuilder().setRef(4).setType(FILE).setPath(FILE_PATH));
163 Component root = underTest.build(project, PROJECT_KEY);
164 assertThat(root.getKey()).isEqualTo(PROJECT_KEY);
165 Component module = root.getChildren().iterator().next();
166 assertThat(module.getName()).isEqualTo(MODULE_KEY);
167 Component directory = module.getChildren().iterator().next();
168 assertThat(directory.getName()).isEqualTo(module.getKey() + ":" + DIRECTORY_PATH);
169 Component file = directory.getChildren().iterator().next();
170 assertThat(file.getName()).isEqualTo(module.getKey() + ":" + FILE_PATH);
174 public void name_of_module_directory_and_file_is_key_of_Scanner_Component_when_name_is_empty() {
175 ScannerReport.Component project = newBuilder().setType(PROJECT).setRef(1).setName("").addChildRef(2).build();
176 scannerComponentProvider.add(newBuilder().setRef(2).setType(MODULE).setKey(MODULE_KEY).setName("").addChildRef(3));
177 scannerComponentProvider.add(newBuilder().setRef(3).setType(DIRECTORY).setPath(DIRECTORY_PATH).setName("").addChildRef(4));
178 scannerComponentProvider.add(newBuilder().setRef(4).setType(FILE).setPath(FILE_PATH).setName(""));
180 Component root = underTest.build(project, PROJECT_KEY);
181 assertThat(root.getKey()).isEqualTo(PROJECT_KEY);
182 Component module = root.getChildren().iterator().next();
183 assertThat(module.getName()).isEqualTo(MODULE_KEY);
184 Component directory = module.getChildren().iterator().next();
185 assertThat(directory.getName()).isEqualTo(module.getKey() + ":" + DIRECTORY_PATH);
186 Component file = directory.getChildren().iterator().next();
187 assertThat(file.getName()).isEqualTo(module.getKey() + ":" + FILE_PATH);
191 public void name_of_module_directory_and_files_includes_name_of_closest_module() {
192 ScannerReport.Component project = newBuilder().setType(PROJECT).setRef(1).addChildRef(11).addChildRef(21).addChildRef(31).build();
193 scannerComponentProvider.add(newBuilder().setRef(11).setType(MODULE).setKey("module 1").addChildRef(12).addChildRef(22).addChildRef(32));
194 scannerComponentProvider.add(newBuilder().setRef(12).setType(MODULE).setKey("module 2").addChildRef(13).addChildRef(23).addChildRef(33));
195 scannerComponentProvider.add(newBuilder().setRef(13).setType(MODULE).setKey("module 3").addChildRef(24).addChildRef(34));
196 scannerComponentProvider.add(newBuilder().setRef(21).setType(DIRECTORY).setPath("directory in project").addChildRef(35));
197 scannerComponentProvider.add(newBuilder().setRef(22).setType(DIRECTORY).setPath("directory in module 1").addChildRef(36));
198 scannerComponentProvider.add(newBuilder().setRef(23).setType(DIRECTORY).setPath("directory in module 2").addChildRef(37));
199 scannerComponentProvider.add(newBuilder().setRef(24).setType(DIRECTORY).setPath("directory in module 3").addChildRef(38));
200 scannerComponentProvider.add(newBuilder().setRef(31).setType(FILE).setPath("file in project"));
201 scannerComponentProvider.add(newBuilder().setRef(32).setType(FILE).setPath("file in module 1"));
202 scannerComponentProvider.add(newBuilder().setRef(33).setType(FILE).setPath("file in module 2"));
203 scannerComponentProvider.add(newBuilder().setRef(34).setType(FILE).setPath("file in module 3"));
204 scannerComponentProvider.add(newBuilder().setRef(35).setType(FILE).setPath("file in directory in project"));
205 scannerComponentProvider.add(newBuilder().setRef(36).setType(FILE).setPath("file in directory in module 1"));
206 scannerComponentProvider.add(newBuilder().setRef(37).setType(FILE).setPath("file in directory in module 2"));
207 scannerComponentProvider.add(newBuilder().setRef(38).setType(FILE).setPath("file in directory in module 3"));
209 Component root = underTest.build(project, PROJECT_KEY);
210 Map<Integer, Component> componentsByRef = indexComponentByRef(root);
211 assertThat(componentsByRef.get(11).getKey()).isEqualTo("module 1");
212 assertThat(componentsByRef.get(12).getKey()).isEqualTo("module 2");
213 assertThat(componentsByRef.get(13).getKey()).isEqualTo("module 3");
214 assertThat(componentsByRef.get(21).getKey()).startsWith(PROJECT_KEY + ":");
215 assertThat(componentsByRef.get(22).getKey()).startsWith("module 1" + ":");
216 assertThat(componentsByRef.get(23).getKey()).startsWith("module 2" + ":");
217 assertThat(componentsByRef.get(24).getKey()).startsWith("module 3" + ":");
218 assertThat(componentsByRef.get(31).getKey()).startsWith(PROJECT_KEY + ":");
219 assertThat(componentsByRef.get(32).getKey()).startsWith("module 1" + ":");
220 assertThat(componentsByRef.get(33).getKey()).startsWith("module 2" + ":");
221 assertThat(componentsByRef.get(34).getKey()).startsWith("module 3" + ":");
222 assertThat(componentsByRef.get(35).getKey()).startsWith(PROJECT_KEY + ":");
223 assertThat(componentsByRef.get(36).getKey()).startsWith("module 1" + ":");
224 assertThat(componentsByRef.get(37).getKey()).startsWith("module 2" + ":");
225 assertThat(componentsByRef.get(38).getKey()).startsWith("module 3" + ":");
229 public void uuid_is_value_from_uuid_supplier_for_project_module_directory_and_file() {
230 ScannerReport.Component project = newBuilder().setType(PROJECT).setRef(1).addChildRef(2).build();
231 scannerComponentProvider.add(newBuilder().setRef(2).setType(MODULE).setKey(MODULE_KEY).addChildRef(3));
232 scannerComponentProvider.add(newBuilder().setRef(3).setType(DIRECTORY).setPath(DIRECTORY_PATH).addChildRef(4));
233 scannerComponentProvider.add(newBuilder().setRef(4).setType(FILE).setPath(FILE_PATH));
235 Component root = underTest.build(project, PROJECT_KEY);
236 Map<Integer, Component> componentByRef = indexComponentByRef(root);
237 assertThat(componentByRef.get(1).getUuid()).isEqualTo(SIMPLE_UUID_GENERATOR.apply(PROJECT_KEY));
238 assertThat(componentByRef.get(2).getUuid()).isEqualTo(SIMPLE_UUID_GENERATOR.apply(MODULE_KEY));
239 assertThat(componentByRef.get(3).getUuid()).isEqualTo(SIMPLE_UUID_GENERATOR.apply(DIRECTORY_KEY));
240 assertThat(componentByRef.get(4).getUuid()).isEqualTo(SIMPLE_UUID_GENERATOR.apply(FILE_KEY));
245 public void description_of_project_module_directory_and_file_is_null_when_unset_in_Scanner_Component() {
246 ScannerReport.Component project = newBuilder().setType(PROJECT).setRef(1).addChildRef(2).build();
247 scannerComponentProvider.add(newBuilder().setRef(2).setType(MODULE).addChildRef(3));
248 scannerComponentProvider.add(newBuilder().setRef(3).setType(DIRECTORY).addChildRef(4));
249 scannerComponentProvider.add(newBuilder().setRef(4).setType(FILE));
251 Component root = underTest.build(project, PROJECT_KEY);
252 Map<Integer, Component> componentByRef = indexComponentByRef(root);
253 assertThat(componentByRef.get(1).getDescription()).isNull();
254 assertThat(componentByRef.get(2).getDescription()).isNull();
255 assertThat(componentByRef.get(3).getDescription()).isNull();
256 assertThat(componentByRef.get(4).getDescription()).isNull();
260 public void description_of_project_module_directory_and_file_is_null_when_empty_in_Scanner_Component() {
261 ScannerReport.Component project = newBuilder().setType(PROJECT).setRef(1).setDescription("").addChildRef(2).build();
262 scannerComponentProvider.add(newBuilder().setRef(2).setType(MODULE).setDescription("").addChildRef(3));
263 scannerComponentProvider.add(newBuilder().setRef(3).setType(DIRECTORY).setDescription("").addChildRef(4));
264 scannerComponentProvider.add(newBuilder().setRef(4).setType(FILE).setDescription(""));
266 Component root = underTest.build(project, PROJECT_KEY);
267 Map<Integer, Component> componentByRef = indexComponentByRef(root);
268 assertThat(componentByRef.get(1).getDescription()).isNull();
269 assertThat(componentByRef.get(2).getDescription()).isNull();
270 assertThat(componentByRef.get(3).getDescription()).isNull();
271 assertThat(componentByRef.get(4).getDescription()).isNull();
275 public void description_of_project_module_directory_and_file_is_description_of_Scanner_Component_when_set() {
276 ScannerReport.Component project = newBuilder().setType(PROJECT).setRef(1).setDescription("desc of project").addChildRef(2).build();
277 scannerComponentProvider.add(newBuilder().setRef(2).setType(MODULE).setDescription("desc of module").addChildRef(3));
278 scannerComponentProvider.add(newBuilder().setRef(3).setType(DIRECTORY).setDescription("desc of directory").addChildRef(4));
279 scannerComponentProvider.add(newBuilder().setRef(4).setType(FILE).setDescription("desc of file"));
281 Component root = underTest.build(project, PROJECT_KEY);
282 Map<Integer, Component> componentByRef = indexComponentByRef(root);
283 assertThat(componentByRef.get(1).getDescription()).isEqualTo("desc of project");
284 assertThat(componentByRef.get(2).getDescription()).isEqualTo("desc of module");
285 assertThat(componentByRef.get(3).getDescription()).isEqualTo("desc of directory");
286 assertThat(componentByRef.get(4).getDescription()).isEqualTo("desc of file");
290 public void all_types_but_UNSET_and_UNRECOGNIZED_are_converted() {
291 Arrays.stream(ScannerReport.Component.ComponentType.values())
292 .filter((type) -> type != UNRECOGNIZED)
293 .filter((type) -> type != UNSET)
294 .forEach((type) -> assertThat(ComponentRootBuilder.convertType(type)).isEqualTo(Component.Type.valueOf(type.name())));
298 public void createReportAttributes_takes_ref_version_and_path_from_Scanner_Component() {
300 String version = "1.0";
301 String path = "some path";
303 ReportAttributes reportAttributes = createReportAttributes(newBuilder()
308 assertThat(reportAttributes.getRef()).isEqualTo(ref);
309 assertThat(reportAttributes.getPath()).isEqualTo(path);
310 assertThat(reportAttributes.getVersion()).isEqualTo(version);
314 public void createReportAttributes_sets_null_version_when_unset_in_Scanner_Component() {
315 ReportAttributes reportAttributes = createReportAttributes(newBuilder().build());
316 assertThat(reportAttributes.getVersion()).isNull();
320 public void createReportAttributes_sets_null_path_when_unset_in_Scanner_Component() {
321 ReportAttributes reportAttributes = createReportAttributes(newBuilder().build());
322 assertThat(reportAttributes.getPath()).isNull();
326 public void createReportAttributes_sets_null_version_when_empty_in_Scanner_Component() {
327 ReportAttributes reportAttributes = createReportAttributes(newBuilder().setVersion("").build());
328 assertThat(reportAttributes.getVersion()).isNull();
332 public void createReportAttributes_sets_null_path_when_empty_in_Scanner_Component() {
333 ReportAttributes reportAttributes = createReportAttributes(newBuilder().setPath("").build());
334 assertThat(reportAttributes.getPath()).isNull();
338 public void createFileAttributes_returns_null_when_type_is_not_FILE() {
339 Arrays.stream(ScannerReport.Component.ComponentType.values())
340 .filter((type) -> type != UNRECOGNIZED)
341 .filter((type) -> type != FILE)
343 (type) -> newBuilder().setType(type).build())
345 (component) -> assertThat(createFileAttributes(component)).isNull());
349 public void createFileAttributes_sets_language_to_null_when_unset_in_Scanner_Component() {
350 assertThat(createFileAttributes(newBuilder().setType(FILE).build()).getLanguageKey()).isNull();
354 public void createFileAttributes_sets_language_to_null_when_empty_in_Scanner_Component() {
355 assertThat(createFileAttributes(newBuilder().setType(FILE).setLanguage("").build()).getLanguageKey()).isNull();
359 public void createFileAttributes_sets_unitTest_from_Scanner_Component() {
360 assertThat(createFileAttributes(newBuilder().setType(FILE).build()).isUnitTest()).isFalse();
361 assertThat(createFileAttributes(newBuilder().setType(FILE).setIsTest(true).build()).isUnitTest()).isTrue();
364 private static class ScannerComponentProvider extends ExternalResource implements Function<Integer, ScannerReport.Component> {
365 private final Map<Integer, ScannerReport.Component> components = new HashMap<>();
368 protected void before() throws Throwable {
373 public ScannerReport.Component apply(Integer componentRef) {
374 return checkNotNull(components.get(componentRef), "No Component for componentRef %s", componentRef);
377 public ScannerReport.Component add(ScannerReport.Component.Builder builder) {
378 ScannerReport.Component component = builder.build();
379 ScannerReport.Component existing = components.put(component.getRef(), component);
380 checkArgument(existing == null, "Component %s already set for ref %s", existing, component.getRef());
385 private static Map<Integer, Component> indexComponentByRef(Component root) {
386 Map<Integer, Component> componentsByRef = new HashMap<>();
387 new DepthTraversalTypeAwareCrawler(
388 new TypeAwareVisitorAdapter(CrawlerDepthLimit.FILE, PRE_ORDER) {
390 public void visitAny(Component any) {
391 componentsByRef.put(any.getReportAttributes().getRef(), any);
394 return componentsByRef;