Browse Source

Enable QA pipeline at SonarSource

tags/5.5-M1
Simon Brandhof 8 years ago
parent
commit
e851411f7f
44 changed files with 53503 additions and 86 deletions
  1. 28
    0
      .cix.yml
  2. 15
    13
      .travis.yml
  3. 36
    0
      cix.sh
  4. 77
    9
      it/it-tests/pom.xml
  5. 6
    3
      it/it-tests/src/test/java/it/Category1Suite.java
  6. 0
    9
      it/it-tests/src/test/java/it/Category4Suite.java
  7. 47
    0
      it/it-tests/src/test/java/it/Category5Suite.java
  8. 3
    1
      it/it-tests/src/test/java/it/settings/SettingsTestRestartingOrchestrator.java
  9. 123
    0
      it/perf-tests/pom.xml
  10. 9
    0
      it/perf-tests/projects/huge-file/pom.xml
  11. 50100
    0
      it/perf-tests/projects/huge-file/src/main/java/huge/HugeFile.java
  12. 6
    0
      it/perf-tests/projects/xoo-sample/sonar-project.properties
  13. 12
    0
      it/perf-tests/projects/xoo-sample/src/main/xoo/sample/Sample.xoo
  14. 6
    0
      it/perf-tests/projects/xoo-sample/src/main/xoo/sample/Sample.xoo.measures
  15. 21
    0
      it/perf-tests/projects/xoo-sample/src/test/xoo/sample/SampleTest.xoo
  16. 7
    0
      it/perf-tests/projects/xoo-sample/src/test/xoo/sample/SampleTest.xoo.measures
  17. 84
    0
      it/perf-tests/src/main/java/org/sonarsource/sonarqube/perf/MavenLogs.java
  18. 61
    0
      it/perf-tests/src/main/java/org/sonarsource/sonarqube/perf/ServerLogs.java
  19. 69
    0
      it/perf-tests/src/main/resources/selenium/rename_findbugs_profile.html
  20. 123
    0
      it/perf-tests/src/test/java/org/sonarsource/sonarqube/perf/PerfRule.java
  21. 103
    0
      it/perf-tests/src/test/java/org/sonarsource/sonarqube/perf/PerfTestCase.java
  22. 130
    0
      it/perf-tests/src/test/java/org/sonarsource/sonarqube/perf/computation/ComputationTest.java
  23. 144
    0
      it/perf-tests/src/test/java/org/sonarsource/sonarqube/perf/scanner/IssuesModeBigTest.java
  24. 52
    0
      it/perf-tests/src/test/java/org/sonarsource/sonarqube/perf/scanner/MavenLogsTest.java
  25. 150
    0
      it/perf-tests/src/test/java/org/sonarsource/sonarqube/perf/scanner/suite/BootstrappingTest.java
  26. 79
    0
      it/perf-tests/src/test/java/org/sonarsource/sonarqube/perf/scanner/suite/DuplicationTest.java
  27. 104
    0
      it/perf-tests/src/test/java/org/sonarsource/sonarqube/perf/scanner/suite/FileSystemTest.java
  28. 106
    0
      it/perf-tests/src/test/java/org/sonarsource/sonarqube/perf/scanner/suite/HighlightingTest.java
  29. 98
    0
      it/perf-tests/src/test/java/org/sonarsource/sonarqube/perf/scanner/suite/IssuesModeTest.java
  30. 113
    0
      it/perf-tests/src/test/java/org/sonarsource/sonarqube/perf/scanner/suite/MemoryTest.java
  31. 59
    0
      it/perf-tests/src/test/java/org/sonarsource/sonarqube/perf/scanner/suite/ScannerPerfTestSuite.java
  32. 84
    0
      it/perf-tests/src/test/java/org/sonarsource/sonarqube/perf/server/ServerTest.java
  33. 187
    0
      it/perf-tests/src/test/java/org/sonarsource/sonarqube/perf/server/WebTest.java
  34. 1111
    0
      it/perf-tests/src/test/resources/java-quality-profile.xml
  35. 12
    0
      it/perf-tests/src/test/resources/one-xoo-issue-per-line.xml
  36. 3
    0
      it/pom.xml
  37. 6
    0
      pom.xml
  38. 12
    0
      run-db-integration-tests.sh
  39. 11
    0
      run-db-unit-tests.sh
  40. 6
    0
      run-perf-tests.sh
  41. 56
    9
      sonar-db/pom.xml
  42. 23
    19
      sonar-db/src/test/java/org/sonar/db/DatabaseCommands.java
  43. 18
    4
      sonar-db/src/test/java/org/sonar/db/version/v50/FeedFileSourcesTest.java
  44. 3
    19
      travis.sh

+ 28
- 0
.cix.yml View File

@@ -0,0 +1,28 @@
# Definition of QA pipeline at SonarSource
#
# Possible values for SLAVE_TYPE: "performance" (for perf tests) and "gva" (for linux machines connected to DB services)


RUN_ACTIVITY:
- run-db-unit-tests-mysql56
- run-db-unit-tests-mssql2012
- run-db-unit-tests-mssql2014
- run-db-unit-tests-oracle11g
- run-db-unit-tests-oracle12c
- run-db-unit-tests-postgresql93

exclude:
- RUN_ACTIVITY: run-db-unit-tests-mysql56
SLAVE_TYPE: performance
- RUN_ACTIVITY: run-db-unit-tests-mssql2012
SLAVE_TYPE: performance
- RUN_ACTIVITY: run-db-unit-tests-mssql2014
SLAVE_TYPE: performance
- RUN_ACTIVITY: run-db-unit-tests-oracle11g
SLAVE_TYPE: performance
- RUN_ACTIVITY: run-db-unit-tests-oracle12c
SLAVE_TYPE: performance
- RUN_ACTIVITY: run-db-unit-tests-postgresql93
SLAVE_TYPE: performance
- RUN_ACTIVITY: run-perf-tests
SLAVE_TYPE: gva

+ 15
- 13
.travis.yml View File

@@ -4,16 +4,16 @@ install: true
jdk: oraclejdk7
script: ./travis.sh

env:
- TARGET=CI
- TARGET=IT IT_CATEGORY=Category1
- TARGET=IT IT_CATEGORY=Category2
- TARGET=IT IT_CATEGORY=Category3
- TARGET=IT IT_CATEGORY=Category4
- TARGET=IT IT_CATEGORY=Plugins
- TARGET=POSTGRES
- TARGET=MYSQL
- TARGET=WEB
#env:
# - TARGET=CI
# - TARGET=IT IT_CATEGORY=Category1
# - TARGET=IT IT_CATEGORY=Category2
# - TARGET=IT IT_CATEGORY=Category3
# - TARGET=IT IT_CATEGORY=Category4
# - TARGET=IT IT_CATEGORY=Plugins
# - TARGET=POSTGRES
# - TARGET=MYSQL
# - TARGET=WEB


matrix:
@@ -27,9 +27,11 @@ cache:
- 'server/sonar-web/node_modules'

before_cache:
- 'find ~/.m2/repository -type d -name \*-SNAPSHOT -exec rm -rf {} \;'
- 'find ~/.m2/repository -name maven-metadata-\* -exec rm {} \;'
- 'find ~/.m2/repository -name resolver-status.properties -exec rm {} \;'
- 'find $HOME/.m2/repository -type d -name \*-SNAPSHOT -exec rm -rf {} \;'
- 'find $HOME/.m2/repository -name maven-metadata-\* -exec rm {} \;'
- 'find $HOME/.m2/repository -name resolver-status.properties -exec rm {} \;'
# remove all the artifacts (JAR, ZIP) that are installed in local repo because of mvn deploy
- rm -rf $HOME/.m2/repository/org/sonarsource/sonarqube

notifications:
email: false

+ 36
- 0
cix.sh View File

@@ -0,0 +1,36 @@
#!/bin/bash
#

set -euo pipefail

case "$RUN_ACTIVITY" in

run-db-unit-tests-*)
DB_ENGINE=`echo $RUN_ACTIVITY | sed "s/run-db-unit-tests-//g"`

./run-db-unit-tests.sh "http://infra.internal.sonarsource.com/jenkins/orch-${DB_ENGINE}.properties"
;;

run-db-integration-tests-*)
DB_ENGINE=`echo $RUN_ACTIVITY | sed "s/run-db-integration-tests-//g" | cut -d \- -f 1`
CATEGORY=`echo $RUN_ACTIVITY | sed "s/run-db-integration-tests-//g" | cut -d \- -f 2`

echo "./run-db-integration-tests.sh $DB_ENGINE $CATEGORY $SLAVE_TYPE"
;;

run-upgrade-tests-*)
DB_ENGINE=`echo $RUN_ACTIVITY | sed "s/run-upgrade-tests-//g"`

echo "./run-upgrade-tests.sh $DB_ENGINE $SLAVE_TYPE"
;;

run-perf-tests)
./run-perf-tests.sh
;;

*)
echo "unknown RUN_ACTIVITY = $RUN_ACTIVITY"
exit 1
;;

esac

+ 77
- 9
it/it-tests/pom.xml View File

@@ -21,19 +21,14 @@
<dependency>
<groupId>org.sonarsource.orchestrator</groupId>
<artifactId>sonar-orchestrator</artifactId>
<version>3.10.1</version>
<version>${orchestrator.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.sonarsource.sonarqube</groupId>
<artifactId>sonar-xoo-plugin</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.sonarsource.sonarqube</groupId>
<groupId>${project.groupId}</groupId>
<artifactId>sonar-application</artifactId>
<version>${project.version}</version>
<type>zip</type>
<scope>provided</scope>
</dependency>
<dependency>
@@ -121,7 +116,7 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>-Xmx128m -Dsonar.runtimeVersion=${project.version}</argLine>
<argLine>-Xmx128m -Dsonar.runtimeVersion=${project.version} -Dmaven.localRepository=${settings.localRepository}</argLine>
<skipTests>${skipIts}</skipTests>
<includes>
<include>*/${category}Suite.java</include>
@@ -131,4 +126,77 @@
</plugins>
</build>

<profiles>
<profile>
<id>qa</id>
<activation>
<property>
<name>env.SONARSOURCE_QA</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-xoo-plugin</id>
<phase>generate-test-resources</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>${project.groupId}</groupId>
<artifactId>sonar-xoo-plugin</artifactId>
<version>${project.version}</version>
<type>sonar-plugin</type>
<overWrite>true</overWrite>
</artifactItem>
</artifactItems>
<outputDirectory>../../plugins/sonar-xoo-plugin/target</outputDirectory>
<overWriteReleases>true</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>with-db-drivers</id>
<activation>
<property>
<name>with-db-drivers</name>
</property>
</activation>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
</dependency>
<dependency>
<groupId>com.microsoft.sqljdbc</groupId>
<artifactId>sqljdbc41</artifactId>
<version>4.1</version>
<scope>system</scope>
<systemPath>${project.basedir}/../../sonar-application/src/main/assembly/lib/jdbc/mssql/sqljdbc41.jar
</systemPath>
</dependency>
</dependencies>
</profile>
</profiles>

</project>

+ 6
- 3
it/it-tests/src/test/java/it/Category1Suite.java View File

@@ -56,13 +56,17 @@ import it.measureHistory.TimeMachineTest;
import it.projectAdministration.BackgroundTasksTest;
import it.projectAdministration.BulkDeletionTest;
import it.projectAdministration.ProjectAdministrationTest;
import it.projectServices.*;
import it.projectServices.AllProjectsTest;
import it.projectServices.ProjectCodeTest;
import it.projectServices.ProjectComparisonTest;
import it.projectServices.ProjectDrilldownTest;
import it.projectServices.ProjectOverviewTest;
import it.projectServices.ProjectWidgetsTest;
import it.qualityGate.QualityGateNotificationTest;
import it.qualityGate.QualityGateTest;
import it.qualityGate.QualityGateUiTest;
import it.settings.PropertySetsTest;
import it.settings.SettingsTest;
import it.settings.SettingsTestRestartingOrchestrator;
import it.settings.SubCategoriesTest;
import it.user.MyAccountPageTest;
import org.junit.ClassRule;
@@ -91,7 +95,6 @@ import static util.ItUtils.xooPlugin;
PropertySetsTest.class,
SubCategoriesTest.class,
SettingsTest.class,
SettingsTestRestartingOrchestrator.class,
// i18n
I18nTest.class,
// quality gate

+ 0
- 9
it/it-tests/src/test/java/it/Category4Suite.java View File

@@ -28,11 +28,7 @@ import it.dbCleaner.PurgeTest;
import it.duplication.CrossProjectDuplicationsOnRemoveFileTest;
import it.duplication.CrossProjectDuplicationsTest;
import it.duplication.DuplicationsTest;
import it.serverSystem.HttpsTest;
import it.serverSystem.RestartTest;
import it.serverSystem.ServerSystemRestartingOrchestrator;
import it.serverSystem.ServerSystemTest;
import it.updateCenter.UpdateCenterTest;
import it.user.FavouriteTest;
import it.user.ForceAuthenticationTest;
import org.junit.ClassRule;
@@ -44,18 +40,13 @@ import static util.ItUtils.xooPlugin;
@RunWith(Suite.class)
@Suite.SuiteClasses({
// server system
RestartTest.class,
HttpsTest.class,
ServerSystemTest.class,
ServerSystemRestartingOrchestrator.class,
// user
ForceAuthenticationTest.class,
FavouriteTest.class,
// component search
ProjectSearchTest.class,
ComponentsWsTest.class,
// update center
UpdateCenterTest.class,
// analysis exclusion
FileExclusionsTest.class,
IssueExclusionsTest.class,

+ 47
- 0
it/it-tests/src/test/java/it/Category5Suite.java View File

@@ -0,0 +1,47 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program 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.
*
* This program 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 it;

import it.serverSystem.HttpsTest;
import it.serverSystem.RestartTest;
import it.serverSystem.ServerSystemRestartingOrchestrator;
import it.settings.SettingsTestRestartingOrchestrator;
import it.updateCenter.UpdateCenterTest;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;

/**
* This suite is reserved to the tests that start their own instance of Orchestrator.
* Indeed multiple instances of Orchestrator can't be started in parallel, so this
* suite does not declare a shared Orchestrator.
*/
@RunWith(Suite.class)
@Suite.SuiteClasses({
ServerSystemRestartingOrchestrator.class,
RestartTest.class,
HttpsTest.class,
SettingsTestRestartingOrchestrator.class,
// update center
UpdateCenterTest.class

})
public class Category5Suite {

}

+ 3
- 1
it/it-tests/src/test/java/it/settings/SettingsTestRestartingOrchestrator.java View File

@@ -29,7 +29,9 @@ import org.junit.Test;
import org.junit.rules.ExpectedException;
import util.selenium.SeleneseTest;

import static util.ItUtils.*;
import static util.ItUtils.pluginArtifact;
import static util.ItUtils.projectDir;
import static util.ItUtils.xooPlugin;

/**
* This class start a new orchestrator on each test case

+ 123
- 0
it/perf-tests/pom.xml View File

@@ -0,0 +1,123 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.sonarsource.sonarqube</groupId>
<artifactId>it</artifactId>
<version>5.5-SNAPSHOT</version>
</parent>

<artifactId>perf-tests</artifactId>
<name>SonarQube :: Performance Tests</name>

<properties>
<category>*</category>
</properties>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>-Dsonar.runtimeVersion=${project.version}</argLine>
<includes>
<include>org/sonarsource/sonarqube/perf/${category}/suite/*TestSuite.java</include>
<!-- not included in suites -->
<include>org/sonarsource/sonarqube/perf/${category}/*Test.java</include>
</includes>
<excludes>
<!-- included into suites -->
<exclude>org/sonarsource/sonarqube/perf/*/suite/*Test.java</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>

<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>sonar-application</artifactId>
<version>${project.version}</version>
<type>zip</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.sonarsource.orchestrator</groupId>
<artifactId>sonar-orchestrator</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.sonar</groupId>
<artifactId>sonar-update-center-common</artifactId>
<version>1.12.1</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<dependency>
<groupId>com.github.kevinsawicki</groupId>
<artifactId>http-request</artifactId>
<version>5.2</version>
</dependency>
<dependency>
<groupId>org.easytesting</groupId>
<artifactId>fest-assert</artifactId>
<version>1.4</version>
<scope>test</scope>
</dependency>
</dependencies>

<profiles>
<profile>
<id>qa</id>
<activation>
<property>
<name>env.SONARSOURCE_QA</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-xoo-plugin</id>
<phase>generate-test-resources</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>${project.groupId}</groupId>
<artifactId>sonar-xoo-plugin</artifactId>
<version>${project.version}</version>
<type>sonar-plugin</type>
<overWrite>true</overWrite>
</artifactItem>
</artifactItems>
<outputDirectory>../../plugins/sonar-xoo-plugin/target</outputDirectory>
<overWriteReleases>true</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>

</profiles>
</project>

+ 9
- 0
it/perf-tests/projects/huge-file/pom.xml View File

@@ -0,0 +1,9 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sonarsource.it.samples</groupId>
<artifactId>huge-file</artifactId>
<version>1.0-SNAPSHOT</version>
<name>Sonar :: Integration Tests :: Huge File</name>
</project>

+ 50100
- 0
it/perf-tests/projects/huge-file/src/main/java/huge/HugeFile.java
File diff suppressed because it is too large
View File


+ 6
- 0
it/perf-tests/projects/xoo-sample/sonar-project.properties View File

@@ -0,0 +1,6 @@
sonar.projectKey=sample
sonar.projectName=Sample
sonar.projectVersion=1.0-SNAPSHOT
sonar.sources=src/main/xoo
sonar.tests=src/test/xoo
sonar.language=xoo

+ 12
- 0
it/perf-tests/projects/xoo-sample/src/main/xoo/sample/Sample.xoo View File

@@ -0,0 +1,12 @@
package sample;

public class Sample {
public Sample(int i) {
int j = i++;
}
private String myMethod() {
return "hello";
}
}

+ 6
- 0
it/perf-tests/projects/xoo-sample/src/main/xoo/sample/Sample.xoo.measures View File

@@ -0,0 +1,6 @@
lines:13
ncloc:13
#Used by dashboard/widgets tests
complexity_in_classes:3
classes:1
comment_lines:0

+ 21
- 0
it/perf-tests/projects/xoo-sample/src/test/xoo/sample/SampleTest.xoo View File

@@ -0,0 +1,21 @@
package sample;

import org.hamcrest.CoreMatchers;
import org.junit.Test;

import static org.junit.Assert.assertThat;

public class SampleTest {

@Test
public void should_return_i() {
Sample sample = new Sample(1);
assertThat(sample.getI(), CoreMatchers.is(1));
}

@Test
public void should_return_to_string() {
assertThat(new Sample(1).toString(), CoreMatchers.is("1"));
}

}

+ 7
- 0
it/perf-tests/projects/xoo-sample/src/test/xoo/sample/SampleTest.xoo.measures View File

@@ -0,0 +1,7 @@
lines:22
ncloc:22
tests:2
test_execution_time:1
skipped_tests:0
test_errors:0
test_failures:0

+ 84
- 0
it/perf-tests/src/main/java/org/sonarsource/sonarqube/perf/MavenLogs.java View File

@@ -0,0 +1,84 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program 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.
*
* This program 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.sonarsource.sonarqube.perf;

import org.apache.commons.lang.StringUtils;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MavenLogs {

/**
* Total time: 6.015s
* Total time: 3:14.025s
*/
public static Long extractTotalTime(String logs) {
Pattern pattern = Pattern.compile(".*Total time: (\\d*:)?(\\d+).(\\d+)s.*");
Matcher matcher = pattern.matcher(logs);
if (matcher.matches()) {
String minutes = StringUtils.defaultIfBlank(StringUtils.removeEnd(matcher.group(1), ":"), "0");
String seconds = StringUtils.defaultIfBlank(matcher.group(2), "0");
String millis = StringUtils.defaultIfBlank(matcher.group(3), "0");

return (Long.parseLong(minutes) * 60000) + (Long.parseLong(seconds) * 1000) + Long.parseLong(millis);
}
return null;
}

/**
* Final Memory: 68M/190M
*/
public static Long extractEndMemory(String logs) {
return extractLong(logs, ".*Final Memory: (\\d+)M/[\\d]+M.*");
}

public static Long extractMaxMemory(String logs) {
return extractLong(logs, ".*Final Memory: [\\d]+M/(\\d+)M.*");
}

private static Long extractLong(String logs, String format) {
Pattern pattern = Pattern.compile(format);
Matcher matcher = pattern.matcher(logs);
if (matcher.matches()) {
String s = matcher.group(1);
return Long.parseLong(s);
}
return null;
}

/**
* 2015.09.29 16:57:45 INFO web[o.s.s.c.q.CeWorkerRunnableImpl] Executed task | project=com.github.kevinsawicki:http-request-parent | id=AVAZm9oHIXrp54OmOeQe | time=2283ms
*/
public static Long extractComputationTotalTime(List<String> logs) {
Pattern pattern = Pattern.compile(".*INFO.*Executed task.* \\| time=(\\d+)ms.*");
for (int i = logs.size() - 1; i >= 0; i--) {
String line = logs.get(i);
Matcher matcher = pattern.matcher(line);
if (matcher.matches()) {
String duration = matcher.group(1);
return Long.parseLong(duration);
}
}

return null;
}
}

+ 61
- 0
it/perf-tests/src/main/java/org/sonarsource/sonarqube/perf/ServerLogs.java View File

@@ -0,0 +1,61 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program 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.
*
* This program 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.sonarsource.sonarqube.perf;

import com.sonar.orchestrator.Orchestrator;
import org.apache.commons.io.FileUtils;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

public class ServerLogs {

static Date extractDate(String line) {
String pattern = "yyyy.MM.dd HH:mm:ss";
SimpleDateFormat format = new SimpleDateFormat(pattern);
if (line.length() > 19) {
try {
return format.parse(line.substring(0, 19));
} catch (Exception e) {
// ignore
}
}
return null;
}

public static Date extractFirstDate(List<String> lines) {
for (String line : lines) {
Date d = ServerLogs.extractDate(line);
if (d != null) {
return d;
}
}
return null;
}

public static void clear(Orchestrator orch) throws IOException {
if (orch.getServer() != null && orch.getServer().getLogs() != null) {
FileUtils.write(orch.getServer().getLogs(), "", false);
}
}

}

+ 69
- 0
it/perf-tests/src/main/resources/selenium/rename_findbugs_profile.html View File

@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head profile="http://selenium-ide.openqa.org/profiles/test-case">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>rename_findbugs_profile</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr>
<td rowspan="1" colspan="3">rename_findbugs_profile</td>
</tr>
</thead>
<tbody>
<tr>
<td>open</td>
<td>/sessions/new</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>login</td>
<td>admin</td>
</tr>
<tr>
<td>type</td>
<td>password</td>
<td>admin</td>
</tr>
<tr>
<td>clickAndWait</td>
<td>commit</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>/profiles</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>id=rename-java_sonar-way-with-findbugs</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>id=new-name</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>id=new-name</td>
<td>findbugs-profile</td>
</tr>
<tr>
<td>clickAndWait</td>
<td>id=rename-submit</td>
<td></td>
</tr>
<tr>
<td>assertText</td>
<td>profiles_java</td>
<td>*findbugs-profile*</td>
</tr>
</tbody>
</table>
</body>
</html>

+ 123
- 0
it/perf-tests/src/test/java/org/sonarsource/sonarqube/perf/PerfRule.java View File

@@ -0,0 +1,123 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program 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.
*
* This program 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.sonarsource.sonarqube.perf;

import com.google.common.base.Joiner;
import org.hamcrest.CustomMatcher;
import org.junit.rules.ErrorCollector;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public abstract class PerfRule extends ErrorCollector {

private final int runCount;
private final List<List<Long>> recordedResults = new ArrayList<List<Long>>();

private int currentRun;
private String testName;

public PerfRule(int runCount) {
this.runCount = runCount;
}

@Override
public Statement apply(final Statement base, Description description) {
this.testName = description.getMethodName();
return new Statement() {
@Override
public void evaluate() throws Throwable {
for (currentRun = 1; currentRun <= runCount; currentRun++) {
recordedResults.add(new ArrayList<Long>());
beforeEachRun();
base.evaluate();
}
verify();
}

};
}

protected abstract void beforeEachRun();

public void assertDurationAround(long duration, long expectedDuration) {
currentResults().add(duration);
if (isLastRun()) {
long meanDuration = computeAverageDurationOfCurrentStep();
double variation = 100.0 * (0.0 + meanDuration - expectedDuration) / expectedDuration;
checkThat(String.format("Expected %d ms in average, got %d ms [%s]", expectedDuration, meanDuration, Joiner.on(",").join(getAllResultsOfCurrentStep())), Math.abs(variation),
new CustomMatcher<Double>(
"a value less than "
+ PerfTestCase.ACCEPTED_DURATION_VARIATION_IN_PERCENTS) {
@Override
public boolean matches(Object item) {
return ((item instanceof Double) && ((Double) item).compareTo(PerfTestCase.ACCEPTED_DURATION_VARIATION_IN_PERCENTS) < 0);
}
});
}
}

private Long[] getAllResultsOfCurrentStep() {
Long[] result = new Long[runCount];
for (int i = 0; i < runCount; i++) {
result[i] = recordedResults.get(i).get(currentResults().size() - 1);
}
return result;
}

private long computeAverageDurationOfCurrentStep() {
Long[] result = getAllResultsOfCurrentStep();
// Compute a truncated mean by ignoring greater value
Arrays.sort(result);
long meanDuration = 0;
for (int i = 0; i < (runCount - 1); i++) {
meanDuration += result[i];
}
meanDuration /= (runCount - 1);
return meanDuration;
}

private List<Long> currentResults() {
return recordedResults.get(currentRun - 1);
}

public void assertDurationLessThan(long duration, final long maxDuration) {
currentResults().add(duration);
if (isLastRun()) {
long meanDuration = computeAverageDurationOfCurrentStep();
checkThat(String.format("Expected less than %d ms in average, got %d ms [%s]", maxDuration, meanDuration, Joiner.on(",").join(getAllResultsOfCurrentStep())), meanDuration,
new CustomMatcher<Long>("a value less than "
+ maxDuration) {
@Override
public boolean matches(Object item) {
return ((item instanceof Long) && ((Long) item).compareTo(maxDuration) < 0);
}
});
}
}

private boolean isLastRun() {
return currentRun == runCount;
}

}

+ 103
- 0
it/perf-tests/src/test/java/org/sonarsource/sonarqube/perf/PerfTestCase.java View File

@@ -0,0 +1,103 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program 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.
*
* This program 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.sonarsource.sonarqube.perf;

import com.sonar.orchestrator.build.SonarScanner;
import com.sonar.orchestrator.locator.FileLocation;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.hamcrest.CustomMatcher;
import org.junit.Rule;
import org.junit.rules.ErrorCollector;
import org.junit.rules.TestName;

import static org.fest.assertions.Assertions.assertThat;

public abstract class PerfTestCase {
static final double ACCEPTED_DURATION_VARIATION_IN_PERCENTS = 8.0;

@Rule
public TestName testName = new TestName();

protected void assertDurationAround(long duration, long expectedDuration) {
double variation = 100.0 * (0.0 + duration - expectedDuration) / expectedDuration;
System.out.printf("Test %s : executed in %d ms (%.2f %% from target)\n", testName.getMethodName(), duration, variation);
assertThat(Math.abs(variation)).as(String.format("Expected %d ms, got %d ms", expectedDuration, duration)).isLessThan(ACCEPTED_DURATION_VARIATION_IN_PERCENTS);
}

protected void assertDurationAround(ErrorCollector collector, long duration, long expectedDuration) {
double variation = 100.0 * (0.0 + duration - expectedDuration) / expectedDuration;
System.out.printf("Test %s : executed in %d ms (%.2f %% from target)\n", testName.getMethodName(), duration, variation);
collector.checkThat(String.format("Expected %d ms, got %d ms", expectedDuration, duration), Math.abs(variation), new CustomMatcher<Double>("a value less than "
+ ACCEPTED_DURATION_VARIATION_IN_PERCENTS) {
@Override
public boolean matches(Object item) {
return ((item instanceof Double) && ((Double) item).compareTo(ACCEPTED_DURATION_VARIATION_IN_PERCENTS) < 0);
}
});
}

protected void assertDurationLessThan(long duration, long maxDuration) {
System.out.printf("Test %s : %d ms (max allowed is %d)\n", testName.getMethodName(), duration, maxDuration);
assertThat(duration).as(String.format("Expected less than %d ms, got %d ms", maxDuration, duration)).isLessThanOrEqualTo(maxDuration);
}

protected void assertDurationLessThan(ErrorCollector collector, long duration, final long maxDuration) {
System.out.printf("Test %s : %d ms (max allowed is %d)\n", testName.getMethodName(), duration, maxDuration);
collector.checkThat(String.format("Expected less than %d ms, got %d ms", maxDuration, duration), duration, new CustomMatcher<Long>("a value less than "
+ maxDuration) {
@Override
public boolean matches(Object item) {
return ((item instanceof Long) && ((Long) item).compareTo(maxDuration) < 0);
}
});
}

protected Properties readProfiling(File baseDir, String moduleKey) throws IOException {
File profilingFile = new File(baseDir, ".sonar/profiling/" + moduleKey + "-profiler.properties");
Properties props = new Properties();
FileInputStream in = FileUtils.openInputStream(profilingFile);
try {
props.load(in);
} finally {
IOUtils.closeQuietly(in);
}
return props;
}

/**
* New batch analysis with most features disabled by default (empty QP, no CPD, no SCM, ...)
*/
public static SonarScanner newScanner(String sonarRunnerOpts, String... props) {
SonarScanner scanner = SonarScanner.create()
.setProperties(
"sonar.scm.disabled", "true",
"sonar.cpd.exclusions", "**")
.setProperties(props);
scanner
.setEnvironmentVariable("SONAR_RUNNER_OPTS", sonarRunnerOpts)
.setProjectDir(FileLocation.of("projects/xoo-sample").getFile());
return scanner;
}
}

+ 130
- 0
it/perf-tests/src/test/java/org/sonarsource/sonarqube/perf/computation/ComputationTest.java View File

@@ -0,0 +1,130 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program 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.
*
* This program 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.sonarsource.sonarqube.perf.computation;

import com.google.common.base.Charsets;
import com.sonar.orchestrator.Orchestrator;
import com.sonar.orchestrator.build.SonarScanner;
import com.sonar.orchestrator.locator.FileLocation;
import org.sonarsource.sonarqube.perf.MavenLogs;
import org.sonarsource.sonarqube.perf.PerfTestCase;
import java.io.File;
import java.io.IOException;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

public class ComputationTest extends PerfTestCase {
private static int MAX_HEAP_SIZE_IN_MEGA = 600;

@ClassRule
public static TemporaryFolder temp = new TemporaryFolder();

@ClassRule
public static Orchestrator orchestrator = Orchestrator
.builderEnv()
.addPlugin(FileLocation.byWildcardMavenFilename(new File("../../plugins/sonar-xoo-plugin/target"), "sonar-xoo-plugin-*.jar"))
.setServerProperty(
"sonar.web.javaOpts",
String.format("-Xms%dm -Xmx%dm -XX:+HeapDumpOnOutOfMemoryError -XX:MaxPermSize=160m -Djava.awt.headless=true", MAX_HEAP_SIZE_IN_MEGA, MAX_HEAP_SIZE_IN_MEGA))
.setServerProperty("sonar.log.level", "DEBUG")
.restoreProfileAtStartup(FileLocation.ofClasspath("/one-xoo-issue-per-line.xml"))
.build();

private static File bigProjectBaseDir;

@BeforeClass
public static void classSetUp() throws IOException {
bigProjectBaseDir = createProject(4, 10, 20);
}

@Before
public void before() throws Exception {
orchestrator.resetData();
}

@Test
public void analyse_big_project() throws Exception {
SonarScanner scanner = SonarScanner.create()
.setProperties(
"sonar.projectKey", "big-project",
"sonar.projectName", "Big Project",
"sonar.projectVersion", "1.0",
"sonar.sources", "src",
"sonar.profile", "one-xoo-issue-per-line")
.setProjectDir(bigProjectBaseDir);

orchestrator.executeBuild(scanner);

assertComputationDurationAround(340000L);
}

private void assertComputationDurationAround(long expectedDuration) throws IOException {
File report = new File(orchestrator.getServer().getLogs().getParent(), "sonar.log");
List<String> logsLines = FileUtils.readLines(report, Charsets.UTF_8);
Long duration = MavenLogs.extractComputationTotalTime(logsLines);

assertDurationAround(duration, expectedDuration);
}

private static File createProject(int dirDepth, int nbDirByLayer, int nbIssuesByFile) throws IOException {
File rootDir = temp.newFolder();
File projectProperties = new File(rootDir, "sonar-project.properties");

StringBuilder moduleListBuilder = new StringBuilder(nbDirByLayer * ("module".length() + 2));

for (int i = 1; i <= nbDirByLayer; i++) {
moduleListBuilder.append("module").append(i);
File moduleDir = new File(rootDir, "module" + i + "/src");
moduleDir.mkdirs();
if (i != nbDirByLayer) {
moduleListBuilder.append(",");
}

createProjectFiles(moduleDir, dirDepth - 1, nbDirByLayer, nbIssuesByFile);
}

FileUtils.write(projectProperties, "sonar.modules=", true);
FileUtils.write(projectProperties, moduleListBuilder.toString(), true);
FileUtils.write(projectProperties, "\n", true);
FileUtils.write(projectProperties, "sonar.source=src", true);

return rootDir;
}

private static void createProjectFiles(File dir, int depth, int nbFilesByDir, int nbIssuesByFile) throws IOException {
dir.mkdir();
for (int i = 1; i <= nbFilesByDir; i++) {
File xooFile = new File(dir, "file" + i + ".xoo");
String line = xooFile.getAbsolutePath() + i + "\n";
FileUtils.write(xooFile, StringUtils.repeat(line, nbIssuesByFile));
File xooMeasureFile = new File(dir, "file" + i + ".xoo.measures");
FileUtils.write(xooMeasureFile, "lines:" + nbIssuesByFile);
if (depth > 1) {
createProjectFiles(new File(dir, "dir" + i), depth - 1, nbFilesByDir, nbIssuesByFile);
}
}
}
}

+ 144
- 0
it/perf-tests/src/test/java/org/sonarsource/sonarqube/perf/scanner/IssuesModeBigTest.java View File

@@ -0,0 +1,144 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program 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.
*
* This program 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.sonarsource.sonarqube.perf.scanner;

import com.sonar.orchestrator.Orchestrator;
import com.sonar.orchestrator.build.SonarScanner;
import com.sonar.orchestrator.locator.FileLocation;
import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonarsource.sonarqube.perf.PerfTestCase;

// Can't afford multiple executions of this long test, so it does not
// use PerfRule
public class IssuesModeBigTest extends PerfTestCase {

@ClassRule
public static TemporaryFolder temp = new TemporaryFolder();

private static File baseProjectDir;

@ClassRule
public static final Orchestrator ORCHESTRATOR = Orchestrator
.builderEnv()
.addPlugin(FileLocation.byWildcardMavenFilename(new File("../../plugins/sonar-xoo-plugin/target"), "sonar-xoo-plugin-*.jar"))
// should not be so high, but required as long embedded h2 is used -> requires more memory on server
.setServerProperty("sonar.web.javaOpts", "-Xmx1G -XX:MaxPermSize=100m -XX:+HeapDumpOnOutOfMemoryError")
.restoreProfileAtStartup(FileLocation.ofClasspath("/one-xoo-issue-per-line.xml"))
.build();

@BeforeClass
public static void setUp() throws Exception {
// Execute a first analysis to prevent any side effects with cache of plugin JAR files
// ORCHESTRATOR.executeBuild(PerfTestCase.newScanner("-Xmx512m -server", "sonar.profile", "one-xoo-issue-per-line"));
generateAndScanProject();
}

@Test
public void issues_mode_scan_big_project() throws IOException {
File userHome = temp.newFolder();
SonarScanner scanner = createScanner();
scanner.setProperty("sonar.analysis.mode", "issues");
scanner.setProperty("sonar.scanAllFiles", "true");
// Use a new home to start with empty cache
scanner.setProperty("sonar.userHome", userHome.getAbsolutePath());
long start = System.currentTimeMillis();
ORCHESTRATOR.executeBuild(scanner);
long firstIssuesDuration = System.currentTimeMillis() - start;
System.out.println("First issues analysis skipping unchanged files: " + firstIssuesDuration + "ms");

// caches are warmed
start = System.currentTimeMillis();
ORCHESTRATOR.executeBuild(scanner);
long secondIssuesDuration = System.currentTimeMillis() - start;
System.out.println("Second issues analysis skipping unchanged files: " + secondIssuesDuration + "ms");

assertDurationAround(secondIssuesDuration, 109_000L);
}

@Test
public void issues_mode_scan_big_project_only_changed() throws IOException {
File userHome = temp.newFolder();
SonarScanner scanner = createScanner();
scanner.setProperty("sonar.analysis.mode", "issues");
// Use a new home to start with empty cache
scanner.setProperty("sonar.userHome", userHome.getAbsolutePath());
long start = System.currentTimeMillis();
ORCHESTRATOR.executeBuild(scanner);
long firstIssuesDuration = System.currentTimeMillis() - start;
System.out.println("First issues analysis: " + firstIssuesDuration + "ms");

// caches are warmed
start = System.currentTimeMillis();
ORCHESTRATOR.executeBuild(scanner);
long secondIssuesDuration = System.currentTimeMillis() - start;
System.out.println("Second issues analysis: " + secondIssuesDuration + "ms");

assertDurationAround(secondIssuesDuration, 69_000L);
}

private static void generateAndScanProject() throws IOException {
ORCHESTRATOR.getServer().provisionProject("big", "xoo-big");
ORCHESTRATOR.getServer().associateProjectToQualityProfile("big", "xoo", "one-xoo-issue-per-line");

baseProjectDir = generateProject();
SonarScanner scanner = createScanner();

long start = System.currentTimeMillis();
ORCHESTRATOR.executeBuild(scanner);
long firstDuration = System.currentTimeMillis() - start;
System.out.println("Publishing: " + firstDuration + "ms");
}

private static File generateProject() throws IOException {
File baseDir = temp.newFolder();
File srcDir = new File(baseDir, "src");
srcDir.mkdir();

int nbFiles = 100;
int lines = 10000;
for (int nb = 1; nb <= nbFiles; nb++) {
File xooFile = new File(srcDir, "sample" + nb + ".xoo");
FileUtils.write(xooFile, StringUtils.repeat(StringUtils.repeat("a", 100) + "\n", lines));
}
return baseDir;
}

private static SonarScanner createScanner() {
SonarScanner scanner = SonarScanner.create()
.setProperties(
"sonar.projectKey", "big",
"sonar.projectName", "xoo-big",
"sonar.projectVersion", "1.0",
"sonar.sources", "src",
"sonar.showProfiling", "true");
scanner
.setEnvironmentVariable("SONAR_RUNNER_OPTS", "-Xmx128m -server -XX:MaxPermSize=64m")
.setProjectDir(baseProjectDir);
return scanner;
}

}

+ 52
- 0
it/perf-tests/src/test/java/org/sonarsource/sonarqube/perf/scanner/MavenLogsTest.java View File

@@ -0,0 +1,52 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program 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.
*
* This program 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.sonarsource.sonarqube.perf.scanner;

import com.google.common.collect.Lists;
import org.sonarsource.sonarqube.perf.MavenLogs;
import org.junit.Test;

import static org.fest.assertions.Assertions.assertThat;

public class MavenLogsTest {
@Test
public void testExtractTotalTime() throws Exception {
assertThat(MavenLogs.extractTotalTime(" Total time: 6.015s ")).isEqualTo(6015);
assertThat(MavenLogs.extractTotalTime(" Total time: 3:14.025s ")).isEqualTo(194025);
}

@Test
public void testMaxMemory() throws Exception {
assertThat(MavenLogs.extractMaxMemory(" Final Memory: 68M/190M ")).isEqualTo(190);
}

@Test
public void testEndMemory() throws Exception {
assertThat(MavenLogs.extractEndMemory(" Final Memory: 68M/190M ")).isEqualTo(68);
}

@Test
public void logs_with_different_computations_take_the_last_one() throws Exception {
assertThat(MavenLogs.extractComputationTotalTime(Lists.newArrayList(
"2015.09.29 16:57:45 INFO web[o.s.s.c.q.CeWorkerRunnableImpl] Executed task | project=com.github.kevinsawicki:http-request-parent | id=AVAZm9oHIXrp54OmOeQe | time=2283ms",
"2015.09.29 16:57:45 INFO web[o.s.s.c.q.CeWorkerRunnableImpl] Executed task | project=com.github.kevinsawicki:http-request-parent | id=AVAZm9oHIXrp54OmOeQe | time=1234ms")))
.isEqualTo(1234L);
}
}

+ 150
- 0
it/perf-tests/src/test/java/org/sonarsource/sonarqube/perf/scanner/suite/BootstrappingTest.java View File

@@ -0,0 +1,150 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program 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.
*
* This program 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.sonarsource.sonarqube.perf.scanner.suite;

import com.sonar.orchestrator.Orchestrator;
import com.sonar.orchestrator.build.BuildResult;
import com.sonar.orchestrator.build.SonarScanner;
import org.sonarsource.sonarqube.perf.MavenLogs;
import org.sonarsource.sonarqube.perf.PerfRule;
import org.sonarsource.sonarqube.perf.PerfTestCase;
import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

@Ignore("Timeout on computation side")
public class BootstrappingTest extends PerfTestCase {

@Rule
public PerfRule perfRule = new PerfRule(4) {
@Override
protected void beforeEachRun() {
orchestrator.resetData();
}
};

@ClassRule
public static TemporaryFolder temp = new TemporaryFolder();

@ClassRule
public static Orchestrator orchestrator = ScannerPerfTestSuite.ORCHESTRATOR;

private static File manyFlatModulesBaseDir;
private static File manyNestedModulesBaseDir;

@BeforeClass
public static void setUp() throws IOException {
// Execute a first analysis to prevent any side effects with cache of plugin JAR files
orchestrator.executeBuild(newScanner("-Xmx512m -server", "sonar.profile", "one-xoo-issue-per-line"));

manyFlatModulesBaseDir = prepareProjectWithManyFlatModules(100);
manyNestedModulesBaseDir = prepareProjectWithManyNestedModules(50);
}

@Test
public void analyzeProjectWith100FlatModules() throws IOException {

SonarScanner scanner = SonarScanner.create()
.setProperties(
"sonar.projectKey", "many-flat-modules",
"sonar.projectName", "Many Flat Modules",
"sonar.projectVersion", "1.0",
"sonar.sources", "",
"sonar.showProfiling", "true");
scanner
.setEnvironmentVariable("SONAR_RUNNER_OPTS", "-Xmx512m -server -XX:MaxPermSize=64m")
.setProjectDir(manyFlatModulesBaseDir);

BuildResult result = orchestrator.executeBuild(scanner);
// First analysis
perfRule.assertDurationAround(MavenLogs.extractTotalTime(result.getLogs()), 22800L);

result = orchestrator.executeBuild(scanner);
// Second analysis is longer since we load project referential
perfRule.assertDurationAround(MavenLogs.extractTotalTime(result.getLogs()), 27200L);
}

private static File prepareProjectWithManyFlatModules(int SIZE) throws IOException {
File baseDir = temp.newFolder();
File projectProps = new File(baseDir, "sonar-project.properties");

StringBuilder moduleListBuilder = new StringBuilder(SIZE * ("module".length() + 2));

for (int i = 1; i <= SIZE; i++) {
moduleListBuilder.append("module").append(i);
File moduleDir = new File(baseDir, "module" + i);
moduleDir.mkdir();
if (i != SIZE) {
moduleListBuilder.append(",");
}
}

FileUtils.write(projectProps, "sonar.modules=", true);
FileUtils.write(projectProps, moduleListBuilder.toString(), true);
FileUtils.write(projectProps, "\n", true);
return baseDir;
}

@Test
public void analyzeProjectWith50NestedModules() throws IOException {
SonarScanner scanner = SonarScanner.create()
.setProperties(
"sonar.projectKey", "many-nested-modules",
"sonar.projectName", "Many Nested Modules",
"sonar.projectVersion", "1.0",
"sonar.sources", "",
"sonar.showProfiling", "true");
scanner.setEnvironmentVariable("SONAR_RUNNER_OPTS", "-Xmx512m -server -XX:MaxPermSize=64m");
scanner.setProjectDir(manyNestedModulesBaseDir);

BuildResult result = orchestrator.executeBuild(scanner);
// First analysis
perfRule.assertDurationAround(MavenLogs.extractTotalTime(result.getLogs()), 8900L);

result = orchestrator.executeBuild(scanner);
// Second analysis
perfRule.assertDurationAround(MavenLogs.extractTotalTime(result.getLogs()), 9300L);
}

private static File prepareProjectWithManyNestedModules(int SIZE) throws IOException {
File baseDir = temp.newFolder();
File currentDir = baseDir;

for (int i = 1; i <= SIZE; i++) {
File projectProps = new File(currentDir, "sonar-project.properties");
FileUtils.write(projectProps, "sonar.modules=module" + i + "\n", true);
if (i >= 1) {
FileUtils.write(projectProps, "sonar.moduleKey=module" + (i - 1), true);
}
File moduleDir = new File(currentDir, "module" + i);
moduleDir.mkdir();
currentDir = moduleDir;
}
FileUtils.write(new File(currentDir, "sonar-project.properties"), "sonar.moduleKey=module" + SIZE, true);
return baseDir;
}

}

+ 79
- 0
it/perf-tests/src/test/java/org/sonarsource/sonarqube/perf/scanner/suite/DuplicationTest.java View File

@@ -0,0 +1,79 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program 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.
*
* This program 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.sonarsource.sonarqube.perf.scanner.suite;

import com.sonar.orchestrator.Orchestrator;
import com.sonar.orchestrator.build.MavenBuild;
import com.sonar.orchestrator.locator.FileLocation;
import org.sonarsource.sonarqube.perf.PerfTestCase;
import java.io.IOException;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ErrorCollector;
import org.junit.rules.TemporaryFolder;
import org.sonar.wsclient.services.Resource;
import org.sonar.wsclient.services.ResourceQuery;

import static org.fest.assertions.Assertions.assertThat;

public class DuplicationTest extends PerfTestCase {

@Rule
public ErrorCollector collector = new ErrorCollector();

@Rule
public TemporaryFolder temp = new TemporaryFolder();

@ClassRule
public static Orchestrator orchestrator = ScannerPerfTestSuite.ORCHESTRATOR;

@BeforeClass
public static void setUp() throws IOException {
// Execute a first analysis to prevent any side effects with cache of plugin JAR files
orchestrator.executeBuild(newScanner("-Xmx512m -server", "sonar.profile", "one-xoo-issue-per-line"));
}

@Before
public void cleanDatabase() {
orchestrator.resetData();
}

/**
* SONAR-3060
*/
@Test
public void hugeJavaFile() {
MavenBuild build = MavenBuild.create(FileLocation.of("projects/huge-file/pom.xml").getFile())
.setEnvironmentVariable("MAVEN_OPTS", "-Xmx1024m")
.setProperty("sonar.sourceEncoding", "UTF-8")
.setCleanSonarGoals();
orchestrator.executeBuild(build);
Resource file = getResource("com.sonarsource.it.samples:huge-file:src/main/java/huge/HugeFile.java");
assertThat(file.getMeasureValue("duplicated_lines")).isGreaterThan(50000.0);
}

private Resource getResource(String key) {
return orchestrator.getServer().getWsClient()
.find(ResourceQuery.createForMetrics(key, "duplicated_lines", "duplicated_blocks", "duplicated_files", "duplicated_lines_density", "useless-duplicated-lines"));
}
}

+ 104
- 0
it/perf-tests/src/test/java/org/sonarsource/sonarqube/perf/scanner/suite/FileSystemTest.java View File

@@ -0,0 +1,104 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program 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.
*
* This program 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.sonarsource.sonarqube.perf.scanner.suite;

import com.sonar.orchestrator.Orchestrator;
import com.sonar.orchestrator.build.SonarRunner;
import org.sonarsource.sonarqube.perf.PerfRule;
import org.sonarsource.sonarqube.perf.PerfTestCase;
import java.io.File;
import java.io.IOException;
import java.util.Properties;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

public class FileSystemTest extends PerfTestCase {

@Rule
public PerfRule perfRule = new PerfRule(4) {
@Override
protected void beforeEachRun() {
orchestrator.resetData();
}
};

@ClassRule
public static TemporaryFolder temp = new TemporaryFolder();

@ClassRule
public static Orchestrator orchestrator = ScannerPerfTestSuite.ORCHESTRATOR;

private static File baseDir;

@BeforeClass
public static void setUp() throws IOException {
// Execute a first analysis to prevent any side effects with cache of plugin JAR files
orchestrator.executeBuild(newScanner("-Xmx512m -server", "sonar.profile", "one-xoo-issue-per-line"));
baseDir = prepareProject();
}

@Before
public void cleanDatabase() {
orchestrator.resetData();
}

@Test
public void indexProjectWith1000BigFilesXmx128() throws IOException {
run(128, 30000L);
}

private void run(int xmx, long expectedDuration) throws IOException {
SonarRunner runner = SonarRunner.create()
.setProperties(
"sonar.projectName", "filesystem xmx" + xmx,
"sonar.projectVersion", "1.0",
"sonar.sources", "src",
"sonar.analysis.mode", "issues",
"sonar.showProfiling", "true")
.setEnvironmentVariable("SONAR_RUNNER_OPTS", "-Xmx" + xmx + "m -server -XX:MaxPermSize=64m")
.setProjectDir(baseDir);

orchestrator.executeBuild(runner);

Properties prof = readProfiling(baseDir, "project");
perfRule.assertDurationAround(Long.valueOf(prof.getProperty("Index filesystem")), expectedDuration);
}

private static File prepareProject() throws IOException {
File baseDir = temp.newFolder();
File srcDir = new File(baseDir, "src");
srcDir.mkdir();

int nbFiles = 1000;
int lines = 10000;
for (int nb = 1; nb <= nbFiles; nb++) {
File xooFile = new File(srcDir, "sample" + nb + ".xoo");
FileUtils.write(xooFile, StringUtils.repeat(StringUtils.repeat("a", 100) + "\n", lines));
}
return baseDir;
}

}

+ 106
- 0
it/perf-tests/src/test/java/org/sonarsource/sonarqube/perf/scanner/suite/HighlightingTest.java View File

@@ -0,0 +1,106 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program 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.
*
* This program 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.sonarsource.sonarqube.perf.scanner.suite;

import com.sonar.orchestrator.Orchestrator;
import com.sonar.orchestrator.build.BuildResult;
import com.sonar.orchestrator.build.SonarScanner;
import java.io.File;
import java.io.IOException;
import java.util.Properties;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonarsource.sonarqube.perf.MavenLogs;
import org.sonarsource.sonarqube.perf.PerfRule;
import org.sonarsource.sonarqube.perf.PerfTestCase;

public class HighlightingTest extends PerfTestCase {

@Rule
public PerfRule perfRule = new PerfRule(4) {
@Override
protected void beforeEachRun() {
orchestrator.resetData();
}
};

@ClassRule
public static TemporaryFolder temp = new TemporaryFolder();

@ClassRule
public static Orchestrator orchestrator = ScannerPerfTestSuite.ORCHESTRATOR;

@BeforeClass
public static void setUp() throws IOException {
// Execute a first analysis to prevent any side effects with cache of plugin JAR files
orchestrator.executeBuild(newScanner("-Xmx512m -server", "sonar.profile", "one-xoo-issue-per-line"));
}

@Before
public void cleanDatabase() {
orchestrator.resetData();
}

@Test
public void computeSyntaxHighlightingOnBigFiles() throws IOException {
File baseDir = temp.newFolder();
File srcDir = new File(baseDir, "src");
srcDir.mkdir();

int nbFiles = 100;
int ruleCount = 100000;
int nblines = 1000;
int linesize = ruleCount / nblines;
for (int nb = 1; nb <= nbFiles; nb++) {
File xooFile = new File(srcDir, "sample" + nb + ".xoo");
File xoohighlightingFile = new File(srcDir, "sample" + nb + ".xoo.highlighting");
FileUtils.write(xooFile, StringUtils.repeat(StringUtils.repeat("a", linesize) + "\n", nblines));
StringBuilder sb = new StringBuilder(16 * ruleCount);
for (int i = 0; i < ruleCount; i++) {
sb.append(i).append(":").append(i + 1).append(":s\n");
}
FileUtils.write(xoohighlightingFile, sb.toString());
}

SonarScanner scanner = SonarScanner.create()
.setProperties(
"sonar.projectKey", "highlighting",
"sonar.projectName", "highlighting",
"sonar.projectVersion", "1.0",
"sonar.sources", "src",
"sonar.showProfiling", "true");
scanner.setEnvironmentVariable("SONAR_RUNNER_OPTS", "-Xmx512m -server -XX:MaxPermSize=64m")
.setProjectDir(baseDir);

BuildResult result = orchestrator.executeBuild(scanner);
System.out.println("Total time: " + MavenLogs.extractTotalTime(result.getLogs()));
perfRule.assertDurationAround(MavenLogs.extractTotalTime(result.getLogs()), 28200L);

Properties prof = readProfiling(baseDir, "highlighting");
perfRule.assertDurationAround(Long.valueOf(prof.getProperty("Xoo Highlighting Sensor")), 10700L);

}
}

+ 98
- 0
it/perf-tests/src/test/java/org/sonarsource/sonarqube/perf/scanner/suite/IssuesModeTest.java View File

@@ -0,0 +1,98 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program 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.
*
* This program 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.sonarsource.sonarqube.perf.scanner.suite;

import com.sonar.orchestrator.Orchestrator;
import com.sonar.orchestrator.build.SonarRunner;
import org.sonarsource.sonarqube.perf.PerfRule;
import org.sonarsource.sonarqube.perf.PerfTestCase;
import java.io.File;
import java.io.IOException;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

public class IssuesModeTest extends PerfTestCase {

@ClassRule
public static Orchestrator orchestrator = ScannerPerfTestSuite.ORCHESTRATOR;

@ClassRule
public static TemporaryFolder temp = new TemporaryFolder();

@Rule
public PerfRule perfRule = new PerfRule(4) {
@Override
protected void beforeEachRun() {
orchestrator.resetData();
}
};

@Before
public void cleanDatabase() {
orchestrator.resetData();
}

@Test
public void issues_mode_scan_xoo_project() throws IOException {
File userHome = temp.newFolder();
orchestrator.getServer().provisionProject("sample", "xoo-sample");
orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "one-xoo-issue-per-line");
SonarRunner runner = newScanner(
"-Xmx512m -server -XX:MaxPermSize=64m",
"sonar.analysis.mode", "issues",
"sonar.userHome", userHome.getAbsolutePath(),
"sonar.showProfiling", "true");
long start = System.currentTimeMillis();
orchestrator.executeBuild(runner);
long duration = System.currentTimeMillis() - start;
System.out.println("Issues analysis: " + duration + "ms");

perfRule.assertDurationAround(duration, 4450L);
}

@Test
public void issues_mode_with_cache_scan_xoo_project() throws IOException {
File userHome = temp.newFolder();
orchestrator.getServer().provisionProject("sample", "xoo-sample");
orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "one-xoo-issue-per-line");
SonarRunner runner = newScanner(
"-Xmx512m -server -XX:MaxPermSize=64m",
"sonar.analysis.mode", "issues",
"sonar.useWsCache", "true",
"sonar.userHome", userHome.getAbsolutePath(),
"sonar.showProfiling", "true");
long start = System.currentTimeMillis();
orchestrator.executeBuild(runner);
long firstDuration = System.currentTimeMillis() - start;
System.out.println("First issues analysis: " + firstDuration + "ms");

// caches are warmed
start = System.currentTimeMillis();
orchestrator.executeBuild(runner);
long secondDuration = System.currentTimeMillis() - start;
System.out.println("Second issues analysis: " + secondDuration + "ms");

perfRule.assertDurationAround(secondDuration, 3350L);
}

}

+ 113
- 0
it/perf-tests/src/test/java/org/sonarsource/sonarqube/perf/scanner/suite/MemoryTest.java View File

@@ -0,0 +1,113 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program 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.
*
* This program 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.sonarsource.sonarqube.perf.scanner.suite;

import com.google.common.base.Strings;
import com.sonar.orchestrator.Orchestrator;
import com.sonar.orchestrator.build.BuildResult;
import com.sonar.orchestrator.build.SonarScanner;
import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonar.wsclient.services.PropertyCreateQuery;
import org.sonarsource.sonarqube.perf.MavenLogs;
import org.sonarsource.sonarqube.perf.PerfRule;
import org.sonarsource.sonarqube.perf.PerfTestCase;

public class MemoryTest extends PerfTestCase {

@Rule
public PerfRule perfRule = new PerfRule(4) {
@Override
protected void beforeEachRun() {
orchestrator.resetData();
}
};

@ClassRule
public static TemporaryFolder temp = new TemporaryFolder();

@ClassRule
public static Orchestrator orchestrator = ScannerPerfTestSuite.ORCHESTRATOR;

@Before
public void cleanDatabase() {
orchestrator.resetData();
}

@Test
public void should_not_fail_with_limited_xmx_memory_and_no_coverage_per_test() {
orchestrator.executeBuild(
newScanner("-Xmx80m -server -XX:-HeapDumpOnOutOfMemoryError"));
}

int DEPTH = 4;

// Property on root module is duplicated in each module so it may be big
@Test
public void analyzeProjectWithManyModulesAndBigProperties() throws IOException {

File baseDir = temp.newFolder();

prepareModule(baseDir, "moduleA", 1);
prepareModule(baseDir, "moduleB", 1);
prepareModule(baseDir, "moduleC", 1);

FileUtils.write(new File(baseDir, "sonar-project.properties"), "sonar.modules=moduleA,moduleB,moduleC\n", true);
FileUtils.write(new File(baseDir, "sonar-project.properties"), "sonar.myBigProp=" + Strings.repeat("A", 10000), true);

SonarScanner scanner = SonarScanner.create()
.setProperties(
"sonar.projectKey", "big-module-tree",
"sonar.projectName", "Big Module Tree",
"sonar.projectVersion", "1.0",
"sonar.sources", "",
"sonar.showProfiling", "true");
scanner.setEnvironmentVariable("SONAR_RUNNER_OPTS", "-Xmx512m -server -XX:MaxPermSize=64m")
.setProjectDir(baseDir);

BuildResult result = orchestrator.executeBuild(scanner);
perfRule.assertDurationAround(MavenLogs.extractTotalTime(result.getLogs()), 5900L);

// Second execution with a property on server side
orchestrator.getServer().getAdminWsClient().create(new PropertyCreateQuery("sonar.anotherBigProp", Strings.repeat("B", 1000), "big-module-tree"));
result = orchestrator.executeBuild(scanner);
perfRule.assertDurationAround(MavenLogs.extractTotalTime(result.getLogs()), 5600L);
}

private void prepareModule(File parentDir, String moduleName, int depth) throws IOException {
File moduleDir = new File(parentDir, moduleName);
moduleDir.mkdir();
File projectProps = new File(moduleDir, "sonar-project.properties");
FileUtils.write(projectProps, "sonar.moduleKey=" + moduleName + "\n", true);
if (depth < DEPTH) {
FileUtils.write(projectProps, "sonar.modules=" + moduleName + "A," + moduleName + "B," + moduleName + "C\n", true);
prepareModule(moduleDir, moduleName + "A", depth + 1);
prepareModule(moduleDir, moduleName + "B", depth + 1);
prepareModule(moduleDir, moduleName + "C", depth + 1);
}
}

}

+ 59
- 0
it/perf-tests/src/test/java/org/sonarsource/sonarqube/perf/scanner/suite/ScannerPerfTestSuite.java View File

@@ -0,0 +1,59 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program 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.
*
* This program 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.sonarsource.sonarqube.perf.scanner.suite;

import com.sonar.orchestrator.Orchestrator;
import com.sonar.orchestrator.locator.FileLocation;
import org.sonarsource.sonarqube.perf.PerfTestCase;
import java.io.File;
import java.io.IOException;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;

@RunWith(Suite.class)
@Suite.SuiteClasses({
BootstrappingTest.class,
DuplicationTest.class,
FileSystemTest.class,
HighlightingTest.class,
MemoryTest.class,
IssuesModeTest.class
})
public class ScannerPerfTestSuite {

@ClassRule
public static final Orchestrator ORCHESTRATOR = Orchestrator
.builderEnv()
.addPlugin(FileLocation.byWildcardMavenFilename(new File("../../plugins/sonar-xoo-plugin/target"), "sonar-xoo-plugin-*.jar"))
// should not be so high, but required as long embedded h2 is used -> requires more memory on server
.setServerProperty("sonar.web.javaOpts", "-Xmx1G -XX:MaxPermSize=100m -XX:+HeapDumpOnOutOfMemoryError")
// Needed by DuplicationTest::hugeJavaFile
.setOrchestratorProperty("javaVersion", "LATEST_RELEASE").addPlugin("java")
.restoreProfileAtStartup(FileLocation.ofClasspath("/one-xoo-issue-per-line.xml"))
.build();

@BeforeClass
public static void setUp() throws IOException {
// Execute a first analysis to prevent any side effects with cache of plugin JAR files
ORCHESTRATOR.executeBuild(PerfTestCase.newScanner("-Xmx512m -server", "sonar.profile", "one-xoo-issue-per-line"));
}
}

+ 84
- 0
it/perf-tests/src/test/java/org/sonarsource/sonarqube/perf/server/ServerTest.java View File

@@ -0,0 +1,84 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program 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.
*
* This program 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.sonarsource.sonarqube.perf.server;

import com.sonar.orchestrator.Orchestrator;
import org.sonarsource.sonarqube.perf.PerfTestCase;
import org.sonarsource.sonarqube.perf.ServerLogs;
import java.io.IOException;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.junit.Test;

public class ServerTest extends PerfTestCase {

// ES + TOMCAT
@Test
public void server_startup_and_shutdown() throws Exception {
String defaultWebJavaOptions = "-Xmx768m -XX:MaxPermSize=160m -XX:+HeapDumpOnOutOfMemoryError -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djruby.management.enabled=false";
Orchestrator orchestrator = Orchestrator.builderEnv()
.setOrchestratorProperty("javaVersion", "LATEST_RELEASE")
.addPlugin("java")

// See http://wiki.apache.org/tomcat/HowTo/FasterStartUp
// Sometimes source of entropy is too small and Tomcat spends ~20 seconds on the step :
// "Creation of SecureRandom instance for session ID generation using [SHA1PRNG]"
// Using /dev/urandom fixes the issue on linux
.setServerProperty("sonar.web.javaOpts", defaultWebJavaOptions + " -Djava.security.egd=file:/dev/./urandom")
.build();
try {
long startupDuration = start(orchestrator);
assertDurationAround(startupDuration, 46000);

long shutdownDuration = stop(orchestrator);
// can't use percent margins because logs are second-grained but not milliseconds
assertDurationLessThan(shutdownDuration, 4000);

} finally {
orchestrator.stop();
}
}

long start(Orchestrator orchestrator) throws IOException {
ServerLogs.clear(orchestrator);
orchestrator.start();
return logsPeriod(orchestrator);
}

long stop(Orchestrator orchestrator) throws Exception {
ServerLogs.clear(orchestrator);
orchestrator.stop();
return logsPeriod(orchestrator);
}

private long logsPeriod(Orchestrator orchestrator) throws IOException {
// compare dates of first and last log
List<String> lines = FileUtils.readLines(orchestrator.getServer().getLogs());
if (lines.size() < 2) {
throw new IllegalStateException("Fail to estimate server shutdown or startup duration. Not enough logs.");
}
Date start = ServerLogs.extractFirstDate(lines);
Collections.reverse(lines);
Date end = ServerLogs.extractFirstDate(lines);
return end.getTime() - start.getTime();
}
}

+ 187
- 0
it/perf-tests/src/test/java/org/sonarsource/sonarqube/perf/server/WebTest.java View File

@@ -0,0 +1,187 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program 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.
*
* This program 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.sonarsource.sonarqube.perf.server;

import com.github.kevinsawicki.http.HttpRequest;
import com.sonar.orchestrator.Orchestrator;
import com.sonar.orchestrator.build.MavenBuild;
import com.sonar.orchestrator.locator.FileLocation;
import org.junit.Ignore;
import org.sonarsource.sonarqube.perf.PerfTestCase;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;

import static org.junit.Assert.fail;

@Ignore("Temporarily disabled as it requires access to IT_SOURCES")
public class WebTest extends PerfTestCase {

static final int DEFAULT_PAGE_TIMEOUT_MS = 1000;

@ClassRule
public static Orchestrator orchestrator = Orchestrator.builderEnv()
.setOrchestratorProperty("javaVersion", "LATEST_RELEASE")
.addPlugin("java")
.restoreProfileAtStartup(FileLocation.ofClasspath("/java-quality-profile.xml"))
.build();

@BeforeClass
public static void scan_struts() throws Exception {
FileLocation strutsHome = orchestrator.getFileLocationOfShared("it-sonar-performancing/struts-1.3.9/pom.xml");
MavenBuild scan = MavenBuild.create(strutsHome.getFile());
scan.setGoals("sonar:sonar -V");
scan.setEnvironmentVariable("MAVEN_OPTS", "-Xmx512m -server");
scan.setProperty("sonar.scm.disabled", "true");
scan.setProperty("sonar.sourceEncoding", "UTF-8");
orchestrator.executeBuild(scan);
}

@Test
public void homepage() throws Exception {
PageStats counters = request("/");
assertDurationLessThan(counters.durationMs, 300);
}

@Test
public void quality_profiles() throws Exception {
PageStats counters = request("/profiles");
assertDurationLessThan(counters.durationMs, DEFAULT_PAGE_TIMEOUT_MS);
}

@Test
public void issues_search() throws Exception {
PageStats counters = request("/issues/search");
assertDurationLessThan(counters.durationMs, 300);
}

@Test
public void measures_search() throws Exception {
PageStats counters = request("/measures");
assertDurationLessThan(counters.durationMs, 550);
}

@Test
public void all_projects() throws Exception {
PageStats counters = request("/all_projects?qualifier=TRK");
assertDurationLessThan(counters.durationMs, 300);
}

@Test
public void project_measures_search() throws Exception {
PageStats counters = request("/measures/search?qualifiers[]=TRK");
assertDurationLessThan(counters.durationMs, 300);
}

@Test
public void file_measures_search() throws Exception {
PageStats counters = request("/measures/search?qualifiers[]=FIL");
assertDurationLessThan(counters.durationMs, 500);
}

@Test
public void struts_dashboard() throws Exception {
PageStats counters = request("/dashboard/index/org.apache.struts:struts-parent?name=Custom");
assertDurationLessThan(counters.durationMs, 400);
}

@Test
public void struts_issues() throws Exception {
PageStats counters = request("/issues/search?componentRoots=org.apache.struts:struts-parent");
assertDurationLessThan(counters.durationMs, 300);
}

@Test
public void struts_issues_drilldown() throws Exception {
PageStats counters = request("/drilldown/issues/org.apache.struts:struts-parent");
assertDurationLessThan(counters.durationMs, 400);
}

@Test
public void struts_measures_drilldown() throws Exception {
PageStats counters = request("/drilldown/measures/org.apache.struts:struts-parent?metric=ncloc");
// sounds too high !
assertDurationLessThan(counters.durationMs, DEFAULT_PAGE_TIMEOUT_MS);
}

@Test
public void struts_debt_overview() throws Exception {
PageStats counters = request("/overview/issues?id=org.apache.struts:struts-parent");
assertDurationLessThan(counters.durationMs, DEFAULT_PAGE_TIMEOUT_MS);
}

@Test
public void stylesheet_file() throws Exception {
PageStats counters = request("/css/sonar.css");
assertDurationLessThan(counters.durationMs, 40);
}

@Test
public void javascript_file() throws Exception {
PageStats counters = request("/js/bundles/sonar.js");
assertDurationLessThan(counters.durationMs, 40);
}

PageStats request(String path) {
String url = orchestrator.getServer().getUrl() + path;

// warm-up
for (int i = 0; i < 5; i++) {
newRequest(url).code();
}

long targetDuration = Long.MAX_VALUE;
long targetSize = 0L;
for (int i = 0; i < 10; i++) {
HttpRequest request = newRequest(url);
long start = System.currentTimeMillis();
if (request.ok()) {
long duration = System.currentTimeMillis() - start;
int size = request.body().length();

if (duration < targetDuration) {
targetDuration = duration;
targetSize = size;
}
System.out.printf("##### Page %50s %7d ms %7d bytes\n", path, duration, size);
}
}
if (targetDuration == Long.MAX_VALUE) {
fail(String.format("Failed to load page: %s", url));
}
return new PageStats(targetDuration, targetSize);
}

private HttpRequest newRequest(String url) {
HttpRequest request = HttpRequest.get(url);
request.followRedirects(false).acceptJson().acceptCharset(HttpRequest.CHARSET_UTF8);
return request;
}

static class PageStats {
long durationMs;
long sizeBytes;

PageStats(long durationMs, long sizeBytes) {
this.durationMs = durationMs;
this.sizeBytes = sizeBytes;
}
}
}

+ 1111
- 0
it/perf-tests/src/test/resources/java-quality-profile.xml
File diff suppressed because it is too large
View File


+ 12
- 0
it/perf-tests/src/test/resources/one-xoo-issue-per-line.xml View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?><!-- Generated by Sonar -->
<profile>
<name>one-xoo-issue-per-line</name>
<language>xoo</language>
<rules>
<rule>
<repositoryKey>xoo</repositoryKey>
<key>OneIssuePerLine</key>
<priority>MAJOR</priority>
</rule>
</rules>
</profile>

+ 3
- 0
it/pom.xml View File

@@ -15,7 +15,10 @@

<properties>
<maven.deploy.skip>true</maven.deploy.skip>
<source.skip>true</source.skip>
<enforcer.skip>true</enforcer.skip>
</properties>

<modules>
<module>it-plugins</module>
<module>it-tests</module>

+ 6
- 0
pom.xml View File

@@ -66,6 +66,7 @@
<slf4j.version>1.7.12</slf4j.version>
<tomcat.version>8.0.30</tomcat.version>
<elasticsearch.version>1.7.2</elasticsearch.version>
<orchestrator.version>3.11-build315</orchestrator.version>
<okhttp.version>2.6.0</okhttp.version>

<protobuf.version>3.0.0-beta-1</protobuf.version>
@@ -737,6 +738,11 @@
<artifactId>mysql-connector-java</artifactId>
<version>5.1.35</version>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.4.0</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>

+ 12
- 0
run-db-integration-tests.sh View File

@@ -0,0 +1,12 @@
#!/bin/bash
set -euo pipefail

ORCHESTRATOR_CONFIG_URL=$1
shift

cd it
mvn verify \
-Dorchestrator.configUrl=$ORCHESTRATOR_CONFIG_URL \
-Dwith-db-drivers \
-Dcategory=Category1 \
-Dsource.skip=true -B -e -V $*

+ 11
- 0
run-db-unit-tests.sh View File

@@ -0,0 +1,11 @@
#!/bin/bash
set -euo pipefail

ORCHESTRATOR_CONFIG_URL=$1
shift

mvn verify \
-pl :sonar-db \
-Dorchestrator.configUrl=$ORCHESTRATOR_CONFIG_URL \
-Dwith-db-drivers \
-B -e -V $*

+ 6
- 0
run-perf-tests.sh View File

@@ -0,0 +1,6 @@
#!/bin/bash
set -euo pipefail

echo 'Run performance tests'
cd it/perf-tests
mvn verify -B -e -V $*

+ 56
- 9
sonar-db/pom.xml View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
@@ -139,12 +140,60 @@
</build>

<profiles>
<profile>
<id>create-db</id>
<activation>
<property>
<name>env.SONARSOURCE_QA</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>download-sq</id>
<goals>
<goal>get</goal>
</goals>
<phase>generate-test-resources</phase>
<configuration>
<artifact>${project.groupId}:sonar-application:${project.version}:zip</artifact>
<transitive>false</transitive>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.sonarsource.orchestrator</groupId>
<artifactId>orchestrator-maven-plugin</artifactId>
<version>${orchestrator.version}</version>
<executions>
<execution>
<id>create-db</id>
<goals>
<goal>create-db</goal>
</goals>
<phase>generate-test-resources</phase>
<configuration>
<sqVersion>${project.version}</sqVersion>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>

<profile>
<!-- SonarSource internal use -->
<id>dbTests</id>
<id>with-db-drivers</id>
<activation>
<property>
<name>dbTests</name>
<name>with-db-drivers</name>
</property>
</activation>
<properties>
@@ -160,18 +209,16 @@
<artifactId>postgresql</artifactId>
</dependency>
<dependency>
<!-- this artifact is located in the SonarSource internal repository -->
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.3.0</version>
<scope>test</scope>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
</dependency>
<dependency>
<groupId>com.microsoft.sqljdbc</groupId>
<artifactId>sqljdbc41</artifactId>
<version>4.1</version>
<scope>system</scope>
<systemPath>${project.basedir}/../sonar-application/src/main/assembly/lib/jdbc/mssql/sqljdbc41.jar</systemPath>
<systemPath>${project.basedir}/../sonar-application/src/main/assembly/lib/jdbc/mssql/sqljdbc41.jar
</systemPath>
</dependency>
</dependencies>
</profile>

+ 23
- 19
sonar-db/src/test/java/org/sonar/db/DatabaseCommands.java View File

@@ -185,27 +185,31 @@ public abstract class DatabaseCommands {
}

public void resetPrimaryKeys(DataSource dataSource) throws SQLException {
Connection connection = dataSource.getConnection();
connection.setAutoCommit(false);

Statement statement = connection.createStatement();
for (String table : DatabaseVersion.TABLES) {
try {
ResultSet result = statement.executeQuery("SELECT CASE WHEN MAX(ID) IS NULL THEN 1 ELSE MAX(ID)+1 END FROM " + table);
result.next();
int maxId = result.getInt(1);
result.close();

for (String resetCommand : resetSequenceSql(table, maxId)) {
statement.executeUpdate(resetCommand);
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
connection = dataSource.getConnection();
connection.setAutoCommit(false);

statement = connection.createStatement();
for (String table : DatabaseVersion.TABLES) {
try {
resultSet = statement.executeQuery("SELECT CASE WHEN MAX(ID) IS NULL THEN 1 ELSE MAX(ID)+1 END FROM " + table);
resultSet.next();
int maxId = resultSet.getInt(1);
resultSet.close();

for (String resetCommand : resetSequenceSql(table, maxId)) {
statement.executeUpdate(resetCommand);
}
connection.commit();
} catch (Exception e) {
connection.rollback(); // this table has no primary key
}
connection.commit();
} catch (Exception e) {
connection.rollback(); // this table has no primary key
}
} finally {
DbUtils.closeQuietly(connection, statement, resultSet);
}

statement.close();
connection.close();
}
}

+ 18
- 4
sonar-db/src/test/java/org/sonar/db/version/v50/FeedFileSourcesTest.java View File

@@ -120,11 +120,10 @@ public class FeedFileSourcesTest {
try {
connection = db.openConnection();

connection.prepareStatement("insert into snapshot_sources " +
db.executeUpdateSql("insert into snapshot_sources " +
"(snapshot_id, data, updated_at) " +
"values " +
"(6, 'class Foo {\r\n // Empty\r\n}\r\n', '2014-10-31 16:44:02.000')")
.executeUpdate();
"(6, 'class Foo {\r\n // Empty\r\n}\r\n', '2014-10-31 16:44:02.000')");

db.executeUpdateSql("insert into snapshot_sources " +
"(snapshot_id, data, updated_at) " +
@@ -137,6 +136,7 @@ public class FeedFileSourcesTest {
"(1, 6, ?)");
revisionStmt.setBytes(1, "1=aef12a;2=abe465;3=afb789;4=afb789".getBytes(StandardCharsets.UTF_8));
revisionStmt.executeUpdate();
revisionStmt.close();

PreparedStatement authorStmt = connection.prepareStatement("insert into project_measures " +
"(metric_id, snapshot_id, " + columnName + ") " +
@@ -144,6 +144,7 @@ public class FeedFileSourcesTest {
"(2, 6, ?)");
authorStmt.setBytes(1, "1=alice;2=bob;3=carol;4=carol".getBytes(StandardCharsets.UTF_8));
authorStmt.executeUpdate();
authorStmt.close();

PreparedStatement dateStmt = connection.prepareStatement("insert into project_measures " +
"(metric_id, snapshot_id, " + columnName + ") " +
@@ -151,6 +152,7 @@ public class FeedFileSourcesTest {
"(3, 6, ?)");
dateStmt.setBytes(1, "1=2014-04-25T12:34:56+0100;2=2014-07-25T12:34:56+0100;3=2014-03-23T12:34:56+0100;4=2014-03-23T12:34:56+0100".getBytes(StandardCharsets.UTF_8));
dateStmt.executeUpdate();
dateStmt.close();

PreparedStatement utHitsStmt = connection.prepareStatement("insert into project_measures " +
"(metric_id, snapshot_id, " + columnName + ") " +
@@ -158,6 +160,7 @@ public class FeedFileSourcesTest {
"(4, 6, ?)");
utHitsStmt.setBytes(1, "1=1;3=0".getBytes(StandardCharsets.UTF_8));
utHitsStmt.executeUpdate();
utHitsStmt.close();

PreparedStatement utCondStmt = connection.prepareStatement("insert into project_measures " +
"(metric_id, snapshot_id, " + columnName + ") " +
@@ -165,6 +168,7 @@ public class FeedFileSourcesTest {
"(5, 6, ?)");
utCondStmt.setBytes(1, "1=4".getBytes(StandardCharsets.UTF_8));
utCondStmt.executeUpdate();
utCondStmt.close();

PreparedStatement utCoveredCondStmt = connection.prepareStatement("insert into project_measures " +
"(metric_id, snapshot_id, " + columnName + ") " +
@@ -172,6 +176,7 @@ public class FeedFileSourcesTest {
"(6, 6, ?)");
utCoveredCondStmt.setBytes(1, "1=2".getBytes(StandardCharsets.UTF_8));
utCoveredCondStmt.executeUpdate();
utCoveredCondStmt.close();

PreparedStatement itHitsStmt = connection.prepareStatement("insert into project_measures " +
"(metric_id, snapshot_id, " + columnName + ") " +
@@ -179,6 +184,7 @@ public class FeedFileSourcesTest {
"(7, 6, ?)");
itHitsStmt.setBytes(1, "1=2;3=0".getBytes(StandardCharsets.UTF_8));
itHitsStmt.executeUpdate();
itHitsStmt.close();

PreparedStatement itCondStmt = connection.prepareStatement("insert into project_measures " +
"(metric_id, snapshot_id, " + columnName + ") " +
@@ -186,6 +192,7 @@ public class FeedFileSourcesTest {
"(8, 6, ?)");
itCondStmt.setBytes(1, "1=5".getBytes(StandardCharsets.UTF_8));
itCondStmt.executeUpdate();
itCondStmt.close();

PreparedStatement itCoveredCondStmt = connection.prepareStatement("insert into project_measures " +
"(metric_id, snapshot_id, " + columnName + ") " +
@@ -193,6 +200,7 @@ public class FeedFileSourcesTest {
"(9, 6, ?)");
itCoveredCondStmt.setBytes(1, "1=3".getBytes(StandardCharsets.UTF_8));
itCoveredCondStmt.executeUpdate();
itCoveredCondStmt.close();

PreparedStatement overallHitsStmt = connection.prepareStatement("insert into project_measures " +
"(metric_id, snapshot_id, " + columnName + ") " +
@@ -200,6 +208,7 @@ public class FeedFileSourcesTest {
"(10, 6, ?)");
overallHitsStmt.setBytes(1, "1=3;3=0".getBytes(StandardCharsets.UTF_8));
overallHitsStmt.executeUpdate();
overallHitsStmt.close();

PreparedStatement overallCondStmt = connection.prepareStatement("insert into project_measures " +
"(metric_id, snapshot_id, " + columnName + ") " +
@@ -207,6 +216,7 @@ public class FeedFileSourcesTest {
"(11, 6, ?)");
overallCondStmt.setBytes(1, "1=6".getBytes(StandardCharsets.UTF_8));
overallCondStmt.executeUpdate();
overallCondStmt.close();

PreparedStatement overallCoveredCondStmt = connection.prepareStatement("insert into project_measures " +
"(metric_id, snapshot_id, " + columnName + ") " +
@@ -214,6 +224,7 @@ public class FeedFileSourcesTest {
"(12, 6, ?)");
overallCoveredCondStmt.setBytes(1, "1=4".getBytes(StandardCharsets.UTF_8));
overallCoveredCondStmt.executeUpdate();
overallCoveredCondStmt.close();

PreparedStatement duplicationDataStmt = connection.prepareStatement("insert into project_measures " +
"(metric_id, snapshot_id, " + columnName + ") " +
@@ -225,6 +236,7 @@ public class FeedFileSourcesTest {
"<duplications><g><b s=\"1\" l=\"1\" r=\"MyProject:src/main/xoo/prj/MyFile.xoo\"/><b s=\"2\" l=\"1\" r=\"MyProject:src/main/xoo/prj/MyFile.xoo\"/><b s=\"3\" l=\"1\" r=\"MyProject:src/main/xoo/prj/AnotherFile.xoo\"/></g></duplications>"
.getBytes(StandardCharsets.UTF_8));
duplicationDataStmt.executeUpdate();
duplicationDataStmt.close();
} finally {
DbUtils.commitAndCloseQuietly(connection);
}
@@ -259,6 +271,7 @@ public class FeedFileSourcesTest {
db.prepareDbUnit(getClass(), "before.xml");

Connection connection = null;
PreparedStatement duplicationDataStmt = null;
try {
connection = db.openConnection();

@@ -273,7 +286,7 @@ public class FeedFileSourcesTest {
"values " +
"(7, '', '2014-10-31 16:44:02.000')");

PreparedStatement duplicationDataStmt = connection.prepareStatement("insert into project_measures " +
duplicationDataStmt = connection.prepareStatement("insert into project_measures " +
"(metric_id, snapshot_id, text_value) " +
"values " +
"(13, 6, ?)");
@@ -284,6 +297,7 @@ public class FeedFileSourcesTest {
.getBytes(StandardCharsets.UTF_8));
duplicationDataStmt.executeUpdate();
} finally {
DbUtils.close(duplicationDataStmt);
DbUtils.commitAndCloseQuietly(connection);
}


+ 3
- 19
travis.sh View File

@@ -4,7 +4,7 @@ set -euo pipefail

function configureTravis {
mkdir ~/.local
curl -sSL https://github.com/SonarSource/travis-utils/tarball/v24 | tar zx --strip-components 1 -C ~/.local
curl -sSL https://github.com/SonarSource/travis-utils/tarball/v25 | tar zx --strip-components 1 -C ~/.local
source ~/.local/bin/install
}
configureTravis
@@ -28,7 +28,7 @@ CI)
-Pdeploy-sonarsource \
-B -e -V

elif [ "$TRAVIS_PULL_REQUEST" != "false" ] && [ -n "${GITHUB_TOKEN-}" ]; then
elif [ "$TRAVIS_PULL_REQUEST" != "false" ] && [ -n "${GITHUB_TOKEN:-}" ]; then
strongEcho 'Build and analyze pull request, no deploy'

# No need for Maven phase "install" as the generated JAR file does not need to be installed
@@ -57,21 +57,6 @@ CI)
fi
;;

POSTGRES)
psql -c 'create database sonar;' -U postgres

runDatabaseCI "postgresql" "jdbc:postgresql://localhost/sonar" "postgres" ""
;;

MYSQL)
mysql -e "CREATE DATABASE sonar CHARACTER SET UTF8;" -uroot
mysql -e "CREATE USER 'sonar'@'localhost' IDENTIFIED BY 'sonar';" -uroot
mysql -e "GRANT ALL ON sonar.* TO 'sonar'@'localhost';" -uroot
mysql -e "FLUSH PRIVILEGES;" -uroot

runDatabaseCI "mysql" "jdbc:mysql://localhost/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance" "sonar" "sonar"
;;

WEB)
set +eu
source ~/.nvm/nvm.sh && nvm install 4
@@ -80,11 +65,10 @@ WEB)
;;

IT)
if [ "$IT_CATEGORY" == "Plugins" ] && [ ! -n "$GITHUB_TOKEN" ]; then
if [ "$IT_CATEGORY" == "Plugins" ] && [ ! -n "${GITHUB_TOKEN:-}" ]; then
echo "This job is ignored as it needs to access a private GitHub repository"
else
start_xvfb

mvn install -Pit,dev -DskipTests -Dcategory=$IT_CATEGORY -Dmaven.test.redirectTestOutputToFile=false -B -V -e -Dsource.skip=true
fi
;;

Loading…
Cancel
Save