]> source.dussan.org Git - sonarqube.git/blob
22b950770fb00d9ff4c98260b316aed9a5c5934d
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2017 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.server.computation.task.projectanalysis.scm;
21
22 import com.google.common.collect.ImmutableList;
23 import java.util.Iterator;
24 import java.util.List;
25 import javax.annotation.Nullable;
26 import org.junit.Rule;
27 import org.junit.Test;
28 import org.sonar.api.utils.System2;
29 import org.sonar.api.utils.log.LogTester;
30 import org.sonar.core.hash.SourceHashComputer;
31 import org.sonar.db.DbTester;
32 import org.sonar.db.protobuf.DbFileSources;
33 import org.sonar.db.source.FileSourceDto;
34 import org.sonar.scanner.protocol.output.ScannerReport;
35 import org.sonar.server.computation.task.projectanalysis.analysis.Analysis;
36 import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
37 import org.sonar.server.computation.task.projectanalysis.analysis.Branch;
38 import org.sonar.server.computation.task.projectanalysis.batch.BatchReportReaderRule;
39 import org.sonar.server.computation.task.projectanalysis.component.Component;
40 import org.sonar.server.computation.task.projectanalysis.component.MergeBranchComponentUuids;
41 import org.sonar.server.computation.task.projectanalysis.scm.ScmInfoRepositoryImpl.NoScmInfo;
42 import org.sonar.server.computation.task.projectanalysis.source.SourceHashRepositoryImpl;
43 import org.sonar.server.computation.task.projectanalysis.source.SourceLinesRepositoryImpl;
44
45 import static org.assertj.core.api.Assertions.assertThat;
46 import static org.mockito.Mockito.mock;
47 import static org.mockito.Mockito.when;
48 import static org.sonar.api.utils.log.LoggerLevel.TRACE;
49 import static org.sonar.server.computation.task.projectanalysis.component.ReportComponent.builder;
50
51 public class ScmInfoDbLoaderTest {
52   static final int FILE_REF = 1;
53   static final Component FILE = builder(Component.Type.FILE, FILE_REF).setKey("FILE_KEY").setUuid("FILE_UUID").build();
54   static final long DATE_1 = 123456789L;
55   static final long DATE_2 = 1234567810L;
56
57   static Analysis baseProjectAnalysis = new Analysis.Builder()
58     .setId(1)
59     .setUuid("uuid_1")
60     .setCreatedAt(123456789L)
61     .build();
62
63   @Rule
64   public LogTester logTester = new LogTester();
65   @Rule
66   public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule();
67   @Rule
68   public DbTester dbTester = DbTester.create(System2.INSTANCE);
69   @Rule
70   public BatchReportReaderRule reportReader = new BatchReportReaderRule();
71
72   private Branch branch = mock(Branch.class);
73   private SourceHashRepositoryImpl sourceHashRepository = new SourceHashRepositoryImpl(new SourceLinesRepositoryImpl(reportReader));
74   private MergeBranchComponentUuids mergeBranchComponentUuids = mock(MergeBranchComponentUuids.class);
75
76   private ScmInfoDbLoader underTest = new ScmInfoDbLoader(analysisMetadataHolder, dbTester.getDbClient(), sourceHashRepository, mergeBranchComponentUuids);
77
78   @Test
79   public void returns_ScmInfo_from_DB_if_hashes_are_the_same() throws Exception {
80     analysisMetadataHolder.setBaseAnalysis(baseProjectAnalysis);
81     analysisMetadataHolder.setBranch(null);
82
83     addFileSourceInDb("henry", DATE_1, "rev-1", computeSourceHash(1));
84     addFileSourceInReport(1);
85
86     ScmInfo scmInfo = underTest.getScmInfoFromDb(FILE);
87     assertThat(scmInfo.getAllChangesets()).hasSize(1);
88
89     assertThat(logTester.logs(TRACE)).containsOnly("Reading SCM info from db for file 'FILE_UUID'");
90   }
91
92   @Test
93   public void read_from_merge_branch_if_no_base() {
94     analysisMetadataHolder.setBaseAnalysis(null);
95     analysisMetadataHolder.setBranch(branch);
96     String mergeFileUuid = "mergeFileUuid";
97
98     when(mergeBranchComponentUuids.getUuid(FILE.getKey())).thenReturn(mergeFileUuid);
99     addFileSourceInDb("henry", DATE_1, "rev-1", computeSourceHash(1), mergeFileUuid);
100     addFileSourceInReport(1);
101
102     ScmInfo scmInfo = underTest.getScmInfoFromDb(FILE);
103     assertThat(scmInfo.getAllChangesets()).hasSize(1);
104     assertThat(logTester.logs(TRACE)).containsOnly("Reading SCM info from db for file 'mergeFileUuid'");
105   }
106
107   @Test
108   public void returns_absent_when_branch_and_source_is_different() {
109     analysisMetadataHolder.setBaseAnalysis(null);
110     analysisMetadataHolder.setBranch(branch);
111     String mergeFileUuid = "mergeFileUuid";
112
113     when(mergeBranchComponentUuids.getUuid(FILE.getKey())).thenReturn(mergeFileUuid);
114     addFileSourceInDb("henry", DATE_1, "rev-1", computeSourceHash(1) + "dif", mergeFileUuid);
115     addFileSourceInReport(1);
116
117     assertThat(underTest.getScmInfoFromDb(FILE)).isEqualTo(NoScmInfo.INSTANCE);
118     assertThat(logTester.logs(TRACE)).containsOnly("Reading SCM info from db for file 'mergeFileUuid'");
119   }
120
121   @Test
122   public void returns_absent_when__hashes_are_not_the_same() throws Exception {
123     analysisMetadataHolder.setBaseAnalysis(baseProjectAnalysis);
124     analysisMetadataHolder.setBranch(null);
125
126     addFileSourceInReport(1);
127     addFileSourceInDb("henry", DATE_1, "rev-1", computeSourceHash(1) + "_different");
128
129     assertThat(underTest.getScmInfoFromDb(FILE)).isEqualTo(NoScmInfo.INSTANCE);
130     assertThat(logTester.logs(TRACE)).containsOnly("Reading SCM info from db for file 'FILE_UUID'");
131   }
132
133   @Test
134   public void not_read_in_db_on_first_analysis() throws Exception {
135     analysisMetadataHolder.setBaseAnalysis(null);
136     analysisMetadataHolder.setBranch(null);
137
138     addFileSourceInReport(1);
139
140     assertThat(underTest.getScmInfoFromDb(FILE)).isEqualTo(NoScmInfo.INSTANCE);
141     assertThat(logTester.logs(TRACE)).isEmpty();
142   }
143
144   private static List<String> generateLines(int lineCount) {
145     ImmutableList.Builder<String> builder = ImmutableList.builder();
146     for (int i = 0; i < lineCount; i++) {
147       builder.add("line " + i);
148     }
149     return builder.build();
150   }
151
152   private static String computeSourceHash(int lineCount) {
153     SourceHashComputer sourceHashComputer = new SourceHashComputer();
154     Iterator<String> lines = generateLines(lineCount).iterator();
155     while (lines.hasNext()) {
156       sourceHashComputer.addLine(lines.next(), lines.hasNext());
157     }
158     return sourceHashComputer.getHash();
159   }
160
161   private void addFileSourceInDb(@Nullable String author, @Nullable Long date, @Nullable String revision, String srcHash) {
162     addFileSourceInDb(author, date, revision, srcHash, FILE.getUuid());
163   }
164
165   private void addFileSourceInDb(@Nullable String author, @Nullable Long date, @Nullable String revision, String srcHash, String fileUuid) {
166     DbFileSources.Data.Builder fileDataBuilder = DbFileSources.Data.newBuilder();
167     DbFileSources.Line.Builder builder = fileDataBuilder.addLinesBuilder()
168       .setLine(1);
169     if (author != null) {
170       builder.setScmAuthor(author);
171     }
172     if (date != null) {
173       builder.setScmDate(date);
174     }
175     if (revision != null) {
176       builder.setScmRevision(revision);
177     }
178     dbTester.getDbClient().fileSourceDao().insert(dbTester.getSession(), new FileSourceDto()
179       .setFileUuid(fileUuid)
180       .setProjectUuid("PROJECT_UUID")
181       .setSourceData(fileDataBuilder.build())
182       .setSrcHash(srcHash));
183     dbTester.commit();
184   }
185
186   private void addFileSourceInReport(int lineCount) {
187     reportReader.putFileSourceLines(FILE_REF, generateLines(lineCount));
188     reportReader.putComponent(ScannerReport.Component.newBuilder()
189       .setRef(FILE_REF)
190       .setLines(lineCount)
191       .build());
192   }
193 }