]> source.dussan.org Git - sonarqube.git/blob
0eb79223ef566ecea0eb73f79140173bdf6d8617
[sonarqube.git] /
1 /*
2  * SonarQube, open source software quality management tool.
3  * Copyright (C) 2008-2014 SonarSource
4  * mailto:contact AT sonarsource DOT com
5  *
6  * SonarQube 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  * SonarQube 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
21 package org.sonar.server.benchmark;
22
23 import java.io.File;
24 import java.io.IOException;
25 import java.util.ArrayList;
26 import java.util.List;
27 import org.apache.commons.io.FileUtils;
28 import org.junit.Rule;
29 import org.junit.Test;
30 import org.junit.rules.TemporaryFolder;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33 import org.sonar.api.utils.System2;
34 import org.sonar.batch.protocol.Constants;
35 import org.sonar.batch.protocol.output.BatchReport;
36 import org.sonar.batch.protocol.output.BatchReportWriter;
37 import org.sonar.core.util.Uuids;
38 import org.sonar.db.DbClient;
39 import org.sonar.db.DbTester;
40 import org.sonar.server.computation.analysis.MutableAnalysisMetadataHolderRule;
41 import org.sonar.server.computation.batch.BatchReportDirectoryHolderImpl;
42 import org.sonar.server.computation.batch.BatchReportReaderImpl;
43 import org.sonar.server.computation.batch.TreeRootHolderRule;
44 import org.sonar.server.computation.component.Component;
45 import org.sonar.server.computation.component.ReportComponent;
46 import org.sonar.server.computation.scm.ScmInfoRepositoryImpl;
47 import org.sonar.server.computation.source.SourceHashRepositoryImpl;
48 import org.sonar.server.computation.source.SourceLinesRepositoryImpl;
49 import org.sonar.server.computation.step.PersistFileSourcesStep;
50
51 import static org.assertj.core.api.Assertions.assertThat;
52
53 public class PersistFileSourcesStepTest {
54
55   public static final Logger LOGGER = LoggerFactory.getLogger("perfTestPersistFileSourcesStep");
56
57   public static final int NUMBER_OF_FILES = 1000;
58   public static final int NUMBER_OF_LINES = 1000;
59   public static final String PROJECT_UUID = Uuids.create();
60
61   @Rule
62   public TemporaryFolder temp = new TemporaryFolder();
63
64   @Rule
65   public DbTester dbTester = DbTester.create(System2.INSTANCE);
66
67   @Rule
68   public Benchmark benchmark = new Benchmark();
69
70   @Rule
71   public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
72
73   @Rule
74   public MutableAnalysisMetadataHolderRule analysisMetadataHolder = new MutableAnalysisMetadataHolderRule();
75
76   @Test
77   public void benchmark() throws Exception {
78     File reportDir = prepareReport();
79     persistFileSources(reportDir);
80   }
81
82   private void persistFileSources(File reportDir) {
83     LOGGER.info("Persist file sources");
84     DbClient dbClient = dbTester.getDbClient();
85
86     long start = System.currentTimeMillis();
87
88     BatchReportDirectoryHolderImpl batchReportDirectoryHolder = new BatchReportDirectoryHolderImpl();
89     batchReportDirectoryHolder.setDirectory(reportDir);
90     org.sonar.server.computation.batch.BatchReportReader batchReportReader = new BatchReportReaderImpl(batchReportDirectoryHolder);
91     analysisMetadataHolder.setIsFirstAnalysis(false);
92     SourceLinesRepositoryImpl sourceLinesRepository = new SourceLinesRepositoryImpl(batchReportReader);
93     SourceHashRepositoryImpl sourceHashRepository = new SourceHashRepositoryImpl(sourceLinesRepository);
94     ScmInfoRepositoryImpl scmInfoRepository = new ScmInfoRepositoryImpl(batchReportReader, analysisMetadataHolder, dbClient, sourceHashRepository);
95     PersistFileSourcesStep step = new PersistFileSourcesStep(dbClient, System2.INSTANCE, treeRootHolder, batchReportReader, sourceLinesRepository, scmInfoRepository);
96     step.execute();
97
98     long end = System.currentTimeMillis();
99     long duration = end - start;
100
101     assertThat(dbTester.countRowsOfTable("file_sources")).isEqualTo(NUMBER_OF_FILES);
102     LOGGER.info(String.format("File sources has been persisted in %d ms", duration));
103
104     benchmark.expectAround("Duration to persist FILE_SOURCES", duration, 125000, Benchmark.DEFAULT_ERROR_MARGIN_PERCENTS);
105   }
106
107   private File prepareReport() throws IOException {
108     LOGGER.info("Create report");
109     File reportDir = temp.newFolder();
110
111     BatchReportWriter writer = new BatchReportWriter(reportDir);
112     writer.writeMetadata(BatchReport.Metadata.newBuilder()
113       .setRootComponentRef(1)
114       .build());
115     BatchReport.Component.Builder project = BatchReport.Component.newBuilder()
116       .setRef(1)
117       .setType(Constants.ComponentType.PROJECT);
118
119     List<Component> components = new ArrayList<>();
120     for (int fileRef = 2; fileRef <= NUMBER_OF_FILES + 1; fileRef++) {
121       components.add(generateFileReport(writer, fileRef));
122       project.addChildRef(fileRef);
123     }
124     treeRootHolder.setRoot(ReportComponent.builder(Component.Type.PROJECT, 1)
125       .setUuid(PROJECT_UUID)
126       .setKey("PROJECT")
127       .addChildren(components.toArray(new Component[components.size()]))
128       .build());
129
130     writer.writeComponent(project.build());
131
132     return reportDir;
133   }
134
135   private Component generateFileReport(BatchReportWriter writer, int fileRef) throws IOException {
136     LineData lineData = new LineData();
137     for (int line = 1; line <= NUMBER_OF_LINES; line++) {
138       lineData.generateLineData(line);
139     }
140     writer.writeComponent(BatchReport.Component.newBuilder()
141       .setRef(fileRef)
142       .setType(Constants.ComponentType.FILE)
143       .setLines(NUMBER_OF_LINES)
144       .build());
145
146     FileUtils.writeLines(writer.getSourceFile(fileRef), lineData.lines);
147     writer.writeComponentCoverage(fileRef, lineData.coverages);
148     writer.writeComponentChangesets(lineData.changesetsBuilder.setComponentRef(fileRef).build());
149     writer.writeComponentSyntaxHighlighting(fileRef, lineData.highlightings);
150     writer.writeComponentSymbols(fileRef, lineData.symbols);
151     writer.writeComponentDuplications(fileRef, lineData.duplications);
152
153     return ReportComponent.builder(Component.Type.FILE, fileRef).setUuid(Uuids.create()).setKey("PROJECT:" + fileRef).build();
154   }
155
156   private static class LineData {
157     List<String> lines = new ArrayList<>();
158     BatchReport.Changesets.Builder changesetsBuilder = BatchReport.Changesets.newBuilder();
159     List<BatchReport.Coverage> coverages = new ArrayList<>();
160     List<BatchReport.SyntaxHighlighting> highlightings = new ArrayList<>();
161     List<BatchReport.Symbol> symbols = new ArrayList<>();
162     List<BatchReport.Duplication> duplications = new ArrayList<>();
163
164     void generateLineData(int line) {
165       lines.add("line-" + line);
166
167       changesetsBuilder.addChangeset(BatchReport.Changesets.Changeset.newBuilder()
168         .setAuthor("author-" + line)
169         .setDate(123456789L)
170         .setRevision("rev-" + line)
171         .build())
172         .addChangesetIndexByLine(line - 1);
173
174       coverages.add(BatchReport.Coverage.newBuilder()
175         .setLine(line)
176         .setConditions(10)
177         .setUtHits(true)
178         .setUtCoveredConditions(2)
179         .setItHits(true)
180         .setItCoveredConditions(3)
181         .setOverallCoveredConditions(4)
182         .build());
183
184       highlightings.add(BatchReport.SyntaxHighlighting.newBuilder()
185         .setRange(BatchReport.TextRange.newBuilder()
186           .setStartLine(line).setEndLine(line)
187           .setStartOffset(1).setEndOffset(3)
188           .build())
189         .setType(Constants.HighlightingType.ANNOTATION)
190         .build());
191
192       symbols.add(BatchReport.Symbol.newBuilder()
193         .setDeclaration(BatchReport.TextRange.newBuilder()
194           .setStartLine(line).setEndLine(line).setStartOffset(2).setEndOffset(4)
195           .build())
196         .addReference(BatchReport.TextRange.newBuilder()
197           .setStartLine(line + 1).setEndLine(line + 1).setStartOffset(1).setEndOffset(3)
198           .build())
199         .build());
200
201       duplications.add(BatchReport.Duplication.newBuilder()
202         .setOriginPosition(BatchReport.TextRange.newBuilder()
203           .setStartLine(line)
204           .setEndLine(line)
205           .build())
206         .addDuplicate(BatchReport.Duplicate.newBuilder()
207           .setRange(BatchReport.TextRange.newBuilder()
208             .setStartLine(line + 1)
209             .setEndLine(line + 1)
210             .build())
211           .build())
212         .build());
213     }
214   }
215
216 }