3 * Copyright (C) 2009-2017 SonarSource SA
4 * mailto:info 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.step;
22 import java.util.Arrays;
23 import java.util.Collections;
24 import java.util.List;
26 import org.junit.Before;
27 import org.junit.Rule;
28 import org.junit.Test;
29 import org.mockito.Mock;
30 import org.mockito.MockitoAnnotations;
31 import org.sonar.api.utils.System2;
32 import org.sonar.db.DbClient;
33 import org.sonar.db.DbSession;
34 import org.sonar.db.DbTester;
35 import org.sonar.db.duplication.DuplicationUnitDto;
36 import org.sonar.scanner.protocol.output.ScannerReport;
37 import org.sonar.server.computation.task.projectanalysis.analysis.Analysis;
38 import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
39 import org.sonar.server.computation.task.projectanalysis.batch.BatchReportReaderRule;
40 import org.sonar.server.computation.task.projectanalysis.component.Component;
41 import org.sonar.server.computation.task.projectanalysis.component.Component.Status;
42 import org.sonar.server.computation.task.projectanalysis.component.ReportComponent;
43 import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule;
44 import org.sonar.server.computation.task.projectanalysis.duplication.CrossProjectDuplicationStatusHolder;
45 import org.sonar.server.computation.task.step.ComputationStep;
47 import static java.util.Collections.singletonList;
48 import static org.assertj.core.api.Assertions.assertThat;
49 import static org.mockito.Mockito.when;
51 public class PersistCrossProjectDuplicationIndexStepTest {
53 private static final int FILE_1_REF = 2;
54 private static final int FILE_2_REF = 3;
55 private static final String FILE_2_UUID = "file2";
57 private static final Component FILE_1 = ReportComponent.builder(Component.Type.FILE, FILE_1_REF).build();
58 private static final Component FILE_2 = ReportComponent.builder(Component.Type.FILE, FILE_2_REF)
59 .setStatus(Status.SAME).setUuid(FILE_2_UUID).build();
61 private static final Component PROJECT = ReportComponent.builder(Component.Type.PROJECT, 1)
66 private static final ScannerReport.CpdTextBlock CPD_TEXT_BLOCK = ScannerReport.CpdTextBlock.newBuilder()
67 .setHash("a8998353e96320ec")
71 private static final String ANALYSIS_UUID = "analysis uuid";
72 private static final String BASE_ANALYSIS_UUID = "base analysis uuid";
75 public DbTester dbTester = DbTester.create(System2.INSTANCE);
77 public BatchReportReaderRule reportReader = new BatchReportReaderRule();
79 public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule().setRoot(PROJECT);
81 public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule();
84 CrossProjectDuplicationStatusHolder crossProjectDuplicationStatusHolder;
86 Analysis baseAnalysis;
88 DbClient dbClient = dbTester.getDbClient();
90 ComputationStep underTest;
93 public void setUp() throws Exception {
94 MockitoAnnotations.initMocks(this);
95 when(baseAnalysis.getUuid()).thenReturn(BASE_ANALYSIS_UUID);
96 analysisMetadataHolder.setUuid(ANALYSIS_UUID);
97 analysisMetadataHolder.setBaseAnalysis(baseAnalysis);
98 analysisMetadataHolder.setIncrementalAnalysis(false);
99 underTest = new PersistCrossProjectDuplicationIndexStep(crossProjectDuplicationStatusHolder, dbClient, treeRootHolder, analysisMetadataHolder, reportReader);
103 public void copy_base_analysis_in_incremental_mode() {
104 when(crossProjectDuplicationStatusHolder.isEnabled()).thenReturn(true);
105 analysisMetadataHolder.setIncrementalAnalysis(true);
106 DuplicationUnitDto dup = new DuplicationUnitDto();
107 dup.setAnalysisUuid(BASE_ANALYSIS_UUID);
108 dup.setComponentUuid(FILE_2_UUID);
113 dup.setIndexInFile(1);
114 try (DbSession session = dbTester.getSession()) {
115 dbClient.duplicationDao().insert(session, dup);
118 assertThat(dbTester.countRowsOfTable("duplications_index")).isEqualTo(1);
121 Map<String, Object> dto = dbTester.selectFirst("select HASH, START_LINE, END_LINE, INDEX_IN_FILE, COMPONENT_UUID, ANALYSIS_UUID "
122 + "from duplications_index where analysis_uuid = '" + ANALYSIS_UUID + "'");
123 assertThat(dto.get("HASH")).isEqualTo("asd");
124 assertThat(dto.get("START_LINE")).isEqualTo(0L);
125 assertThat(dto.get("END_LINE")).isEqualTo(0L);
126 assertThat(dto.get("INDEX_IN_FILE")).isEqualTo(0L);
127 assertThat(dto.get("COMPONENT_UUID")).isEqualTo(FILE_2.getUuid());
128 assertThat(dto.get("ANALYSIS_UUID")).isEqualTo(ANALYSIS_UUID);
132 public void persist_cpd_text_block() throws Exception {
133 when(crossProjectDuplicationStatusHolder.isEnabled()).thenReturn(true);
134 reportReader.putDuplicationBlocks(FILE_1_REF, singletonList(CPD_TEXT_BLOCK));
138 Map<String, Object> dto = dbTester.selectFirst("select HASH, START_LINE, END_LINE, INDEX_IN_FILE, COMPONENT_UUID, ANALYSIS_UUID from duplications_index");
139 assertThat(dto.get("HASH")).isEqualTo(CPD_TEXT_BLOCK.getHash());
140 assertThat(dto.get("START_LINE")).isEqualTo(30L);
141 assertThat(dto.get("END_LINE")).isEqualTo(45L);
142 assertThat(dto.get("INDEX_IN_FILE")).isEqualTo(0L);
143 assertThat(dto.get("COMPONENT_UUID")).isEqualTo(FILE_1.getUuid());
144 assertThat(dto.get("ANALYSIS_UUID")).isEqualTo(ANALYSIS_UUID);
148 public void persist_many_cpd_text_blocks() throws Exception {
149 when(crossProjectDuplicationStatusHolder.isEnabled()).thenReturn(true);
150 reportReader.putDuplicationBlocks(FILE_1_REF, Arrays.asList(
152 ScannerReport.CpdTextBlock.newBuilder()
153 .setHash("b1234353e96320ff")
160 List<Map<String, Object>> dtos = dbTester.select("select HASH, START_LINE, END_LINE, INDEX_IN_FILE, COMPONENT_UUID, ANALYSIS_UUID from duplications_index");
161 assertThat(dtos).extracting("HASH").containsOnly(CPD_TEXT_BLOCK.getHash(), "b1234353e96320ff");
162 assertThat(dtos).extracting("START_LINE").containsOnly(30L, 20L);
163 assertThat(dtos).extracting("END_LINE").containsOnly(45L, 15L);
164 assertThat(dtos).extracting("INDEX_IN_FILE").containsOnly(0L, 1L);
165 assertThat(dtos).extracting("COMPONENT_UUID").containsOnly(FILE_1.getUuid());
166 assertThat(dtos).extracting("ANALYSIS_UUID").containsOnly(ANALYSIS_UUID);
170 public void nothing_to_persist_when_no_cpd_text_blocks_in_report() throws Exception {
171 when(crossProjectDuplicationStatusHolder.isEnabled()).thenReturn(true);
172 reportReader.putDuplicationBlocks(FILE_1_REF, Collections.<ScannerReport.CpdTextBlock>emptyList());
176 assertThat(dbTester.countRowsOfTable("duplications_index")).isEqualTo(0);
180 public void nothing_to_do_when_cross_project_duplication_is_disabled() throws Exception {
181 when(crossProjectDuplicationStatusHolder.isEnabled()).thenReturn(false);
182 reportReader.putDuplicationBlocks(FILE_1_REF, singletonList(CPD_TEXT_BLOCK));
186 assertThat(dbTester.countRowsOfTable("duplications_index")).isEqualTo(0);