From: Julien Lancelot Date: Tue, 21 Apr 2015 15:20:23 +0000 (+0200) Subject: SONAR-6258 Add performance test on file sources persistence X-Git-Tag: 5.2-RC1~2166 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=cf172b28653ef2fb75a7b2c30acadac4dad6ee33;p=sonarqube.git SONAR-6258 Add performance test on file sources persistence --- diff --git a/server/sonar-server-benchmarks/src/test/java/org/sonar/server/benchmark/PersistFileSourcesStepTest.java b/server/sonar-server-benchmarks/src/test/java/org/sonar/server/benchmark/PersistFileSourcesStepTest.java new file mode 100644 index 00000000000..d5010a3cb77 --- /dev/null +++ b/server/sonar-server-benchmarks/src/test/java/org/sonar/server/benchmark/PersistFileSourcesStepTest.java @@ -0,0 +1,195 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.sonar.server.benchmark; + +import org.apache.commons.io.FileUtils; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.api.utils.System2; +import org.sonar.api.utils.internal.Uuids; +import org.sonar.batch.protocol.Constants; +import org.sonar.batch.protocol.output.BatchReport; +import org.sonar.batch.protocol.output.BatchReportReader; +import org.sonar.batch.protocol.output.BatchReportWriter; +import org.sonar.core.persistence.DbTester; +import org.sonar.server.component.ComponentTesting; +import org.sonar.server.computation.ComputationContext; +import org.sonar.server.computation.step.PersistFileSourcesStep; +import org.sonar.server.db.DbClient; +import org.sonar.server.source.db.FileSourceDao; + +import java.io.File; +import java.io.IOException; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class PersistFileSourcesStepTest { + + public static final Logger LOGGER = LoggerFactory.getLogger("perfTestPersistFileSourcesStep"); + + public static final int NUMBER_OF_FILES = 1000; + public static final int NUMBER_OF_LINES = 1000; + public static final String PROJECT_UUID = Uuids.create(); + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + @Rule + public DbTester dbTester = new DbTester(); + + @Rule + public Benchmark benchmark = new Benchmark(); + + @Test + public void benchmark() throws Exception { + File reportDir = prepareReport(); + persistFileSources(reportDir); + } + + private void persistFileSources(File reportDir) throws SQLException { + LOGGER.info("Persist file sources"); + DbClient dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new FileSourceDao(dbTester.myBatis())); + + long start = System.currentTimeMillis(); + + PersistFileSourcesStep step = new PersistFileSourcesStep(dbClient, System2.INSTANCE); + step.execute(new ComputationContext(new BatchReportReader(reportDir), ComponentTesting.newProjectDto(PROJECT_UUID))); + + long end = System.currentTimeMillis(); + long duration = end - start; + + assertThat(dbTester.countRowsOfTable("file_sources")).isEqualTo(NUMBER_OF_FILES); + LOGGER.info(String.format("File sources has been persisted in %d ms", duration)); + + // TODO to be enabled after some execution has been done to set a valuable duration + //benchmark.expectAround("Duration to persist FILE_SOURCES", duration, 100000, Benchmark.DEFAULT_ERROR_MARGIN_PERCENTS); + } + + private File prepareReport() throws IOException { + LOGGER.info("Create report"); + File reportDir = temp.newFolder(); + + BatchReportWriter writer = new BatchReportWriter(reportDir); + writer.writeMetadata(BatchReport.Metadata.newBuilder() + .setRootComponentRef(1) + .build()); + BatchReport.Component.Builder project = BatchReport.Component.newBuilder() + .setRef(1) + .setType(Constants.ComponentType.PROJECT) + .setUuid(PROJECT_UUID); + + for (int fileRef = 2; fileRef <= NUMBER_OF_FILES + 1; fileRef++) { + generateFileReport(writer, fileRef); + project.addChildRef(fileRef); + } + + writer.writeComponent(project.build()); + + return reportDir; + } + + private void generateFileReport(BatchReportWriter writer, int fileRef) throws IOException { + LineData lineData = new LineData(); + for (int line = 1; line <= NUMBER_OF_LINES; line++) { + lineData.generateLineData(line); + } + writer.writeComponent(BatchReport.Component.newBuilder() + .setRef(fileRef) + .setType(Constants.ComponentType.FILE) + .setUuid(Uuids.create()) + .setLines(NUMBER_OF_LINES) + .build()); + + FileUtils.writeLines(writer.getSourceFile(fileRef), lineData.lines); + writer.writeComponentCoverage(fileRef, lineData.coverages); + writer.writeComponentChangesets(lineData.changesetsBuilder.setComponentRef(fileRef).build()); + writer.writeComponentSyntaxHighlighting(fileRef, lineData.highlightings); + writer.writeComponentSymbols(fileRef, lineData.symbols); + writer.writeComponentDuplications(fileRef, lineData.duplications); + } + + private static class LineData { + List lines = new ArrayList<>(); + BatchReport.Changesets.Builder changesetsBuilder = BatchReport.Changesets.newBuilder(); + List coverages = new ArrayList<>(); + List highlightings = new ArrayList<>(); + List symbols = new ArrayList<>(); + List duplications = new ArrayList<>(); + + void generateLineData(int line){ + lines.add("line-" + line); + + changesetsBuilder.addChangeset(BatchReport.Changesets.Changeset.newBuilder() + .setAuthor("author-" + line) + .setDate(123456789L) + .setRevision("rev-" + line) + .build()) + .addChangesetIndexByLine(line - 1); + + coverages.add(BatchReport.Coverage.newBuilder() + .setLine(line) + .setConditions(10) + .setUtHits(true) + .setUtCoveredConditions(2) + .setItHits(true) + .setItCoveredConditions(3) + .setOverallCoveredConditions(4) + .build()); + + highlightings.add(BatchReport.SyntaxHighlighting.newBuilder() + .setRange(BatchReport.Range.newBuilder() + .setStartLine(line).setEndLine(line) + .setStartOffset(1).setEndOffset(3) + .build()) + .setType(Constants.HighlightingType.ANNOTATION) + .build()); + + symbols.add(BatchReport.Symbols.Symbol.newBuilder() + .setDeclaration(BatchReport.Range.newBuilder() + .setStartLine(line).setEndLine(line).setStartOffset(2).setEndOffset(4) + .build()) + .addReference(BatchReport.Range.newBuilder() + .setStartLine(line + 1).setEndLine(line + 1).setStartOffset(1).setEndOffset(3) + .build() + ).build()); + + duplications.add(BatchReport.Duplication.newBuilder() + .setOriginPosition(BatchReport.Range.newBuilder() + .setStartLine(line) + .setEndLine(line) + .build()) + .addDuplicate(BatchReport.Duplicate.newBuilder() + .setRange(BatchReport.Range.newBuilder() + .setStartLine(line + 1) + .setEndLine(line + 1) + .build()) + .build()) + .build()); + } + } + +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistFileSourcesStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistFileSourcesStepTest.java index 4acde66990a..ce4b50c9fa1 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistFileSourcesStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistFileSourcesStepTest.java @@ -467,7 +467,7 @@ public class PersistFileSourcesStepTest extends BaseStepTest { for (int i = 1; i <= numberOfLines; i++) { lines.add("line" + i); } - FileUtils.writeLines(writer.getFileStructure().fileFor(FileStructure.Domain.SOURCE, FILE_REF), lines); + FileUtils.writeLines(writer.getSourceFile(FILE_REF), lines); return writer; }