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