blob: 28519dd82df9a6812b99ce2b91da739e32e364e0 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
buildscript {
repositories {
maven { url "https://plugins.gradle.org/m2/" }
}
dependencies {
classpath "gradle.plugin.org.nosphere.apache:creadur-rat-gradle:0.2.0"
classpath "org.ajoberstar:gradle-git:1.3.2"
classpath 'com.bmuschko:gradle-nexus-plugin:2.3.1'
}
}
apply from: 'gradle/rat.gradle'
apply plugin: 'wrapper'
// Load all properties in dependency-version.properties as project properties, so all projects can read them
Properties dependencyVersions = new Properties()
dependencyVersions.load(new FileInputStream("${project.projectDir}/gradle/dependency-versions.properties"))
dependencyVersions.keys().each{ k -> project.ext[k] = dependencyVersions[k]}
allprojects {
version = versionNumber + '-' + releaseType
ext.isReleaseVersion = !version.endsWith("SNAPSHOT")
// We want to see all test results. This is equivalatent to setting --continue
// on the command line.
gradle.startParameter.continueOnFailure = true
repositories {
mavenLocal()
mavenCentral()
maven { url "http://repo.spring.io/release" }
maven { url "http://repo.spring.io/milestone" }
maven { url "http://repo.spring.io/snapshot" }
maven { url "http://repo.spring.io/libs-release" }
maven { url "http://repo.spring.io/ext-release-local" }
maven { url "http://dist.gemstone.com/maven/release" }
}
group = "org.apache.geode"
apply plugin: 'idea'
apply plugin: 'eclipse'
buildRoot = buildRoot.trim()
if (!buildRoot.isEmpty()) {
buildDir = buildRoot + project.path.replace(":", "/") + "/build"
}
gradle.taskGraph.whenReady( { graph ->
tasks.withType(Tar).each { tar ->
tar.compression = Compression.GZIP
tar.extension = 'tar.gz'
}
})
}
task clean (type: Delete) {
delete rootProject.buildDir
if (!buildRoot.isEmpty()) {
delete buildRoot
}
}
def testResultsDir(def parent, def name) {
new File(parent, name)
}
def writeTestProperties(def parent, def name) {
def availablePortFinder = AvailablePortFinder.createPrivate()
def props = new Properties()
props.setProperty('mcast-port', Integer.toString(availablePortFinder.nextAvailable))
props.setProperty('log-level', 'config')
def propsFile = new File(testResultsDir(parent, name), 'gemfire.properties')
def writer = propsFile.newWriter()
props.store(writer, 'Autogenerated Gemfire properties')
}
task combineReports(type: TestReport) {
description 'Combines the test reports.'
destinationDir = file "${rootProject.buildDir}/reports/combined"
doLast {
println "All test reports at ${rootProject.buildDir}/reports/combined"
}
}
gradle.taskGraph.whenReady({ graph ->
tasks.getByName('combineReports').reportOn rootProject.subprojects.collect{ it.tasks.withType(Test) }.flatten()
})
subprojects {
apply plugin: 'java'
// apply compiler options
gradle.taskGraph.whenReady( { graph ->
tasks.withType(JavaCompile).each { javac ->
javac.configure {
sourceCompatibility '1.8'
targetCompatibility '1.8'
options.encoding = 'UTF-8'
}
}
})
// apply default manifest
gradle.taskGraph.whenReady( { graph ->
tasks.withType(Jar).each { jar ->
jar.doFirst {
manifest {
attributes(
"Manifest-Version" : "1.0",
"Created-By" : System.getProperty("user.name"),
"Title" : rootProject.name,
"Version" : version,
"Organization" : "Apache Software Foundation (ASF)"
)
}
}
}
})
configurations {
provided {
description 'a dependency that is provided externally at runtime'
visible true
}
testOutput {
extendsFrom testCompile
description 'a dependency that exposes test artifacts'
}
}
// Here we want to disable all transitive dependencies on external artifacts. This
// allows us to lock down library versions. However, we want project dependencies to
// be transitive such that the libraries of a dependent project are automatically included.
configurations.all {
dependencies.all { dep ->
if (dep instanceof ModuleDependency && !(dep instanceof ProjectDependency)) {
dep.transitive = false
}
}
}
// Configuration for Checkstyle, FindBugs
if (project.hasProperty("staticAnalysis")) {
apply plugin: 'checkstyle'
//Checkstyle configuration
configurations.checkstyle {
dependencies.all { dep ->
dep.transitive = true
}
}
//Findbugs configuration
apply plugin: 'findbugs'
configurations.findbugs {
dependencies.all { dep ->
dep.transitive = true
}
}
// Switch default Findbugs report to HTML for developers
def findbugsXmlEnabled = false
def findbugsHtmlEnabled = true
// Provide ability to change report type to XML for ingesting into other ap
if ( project.hasProperty("findbugsXmlReport") ) {
findbugsXmlEnabled = true
findbugsHtmlEnabled = false
}
configurations.findbugs {
dependencies.all { dep ->
dep.transitive = true
}
findbugs.effort = 'max'
findbugs.reportLevel = 'low'
}
tasks.withType(FindBugs) {
reports {
xml.enabled = findbugsXmlEnabled
html.enabled = findbugsHtmlEnabled
}
}
}
// JaCoCo configuration
if (project.hasProperty("codeCoverage")) {
apply plugin: 'jacoco'
configurations.jacocoAnt {
dependencies.all { dep ->
dep.transitive = true
}
}
task mergeIntegrationTestCoverage (type: JacocoMerge) {
description 'Merges Distributed and Integration test coverage results'
destinationFile = file("${buildDir}/jacoco/mergedIntegrationTestCoverage.exec")
executionData = fileTree(dir: 'build/jacoco', include: ['**/distributedTest.exec','**/integrationTest.exec'])
}
jacocoTestReport {
reports {
csv.enabled false
sourceSets project.sourceSets.main
html.destination "${buildDir}/jacocoTestHtml"
}
}
task jacocoIntegrationTestReport (type: JacocoReport) {
reports {
csv.enabled false
sourceSets project.sourceSets.main
html.destination "${buildDir}/jacocoIntegrationTestHtml"
executionData = fileTree(dir: 'build/jacoco', include: '**/integrationTest.exec')
}
}
task jacocoDistributedTestReport (type: JacocoReport) {
reports {
csv.enabled false
sourceSets project.sourceSets.main
html.destination "${buildDir}/jacocoDistributedTestHtml"
executionData = fileTree(dir: 'build/jacoco', include: '**/distributedTest.exec')
}
}
task jacocoOverallTestReport (type: JacocoReport) {
reports {
csv.enabled false
sourceSets project.sourceSets.main
html.destination "${buildDir}/jacocoOverallTestHtml"
executionData = fileTree(dir: 'build/jacoco', include: '**/*.exec')
}
}
}
eclipse {
classpath {
defaultOutputDir = file('build-eclipse')
downloadSources = true
plusConfigurations += [ configurations.provided ]
}
// Several files have UTF-8 encoding and Eclipse running on Windows
// will have trouble unless we tell it to use UTF-8 encoding.
// This setting needs to go into the core.resources.prefs file,
// which the JDT script isn't set up to configure
eclipseJdt << {
File f = file('.settings/org.eclipse.core.resources.prefs')
f.write('eclipse.preferences.version=1\n')
f.append('encoding/<project>=utf-8')
}
}
cleanEclipse << {
delete '.settings/org.eclipse.core.resources.prefs'
}
tasks.eclipse.dependsOn(cleanEclipse)
idea {
module {
downloadSources = true
scopes.PROVIDED.plus += [ configurations.provided ]
}
}
task jarTest (type: Jar, dependsOn: testClasses) {
description 'Assembles a jar archive of test classes.'
from sourceSets.test.output
classifier 'test'
}
artifacts {
testOutput jarTest
}
sourceSets {
main.compileClasspath += configurations.provided
main.runtimeClasspath -= configurations.provided
test.compileClasspath += configurations.provided
test.runtimeClasspath += configurations.provided
}
javadoc.classpath += configurations.provided
javadoc {
options.addStringOption('Xdoclint:none', '-quiet')
options.encoding='UTF-8'
}
dependencies {
compile 'org.springframework:spring-aop:' + project.'springframework.version'
compile 'org.springframework:spring-beans:' + project.'springframework.version'
compile 'org.springframework:spring-context:' + project.'springframework.version'
compile 'org.springframework:spring-context-support:' + project.'springframework.version'
compile 'org.springframework:spring-core:' + project.'springframework.version'
compile 'org.springframework:spring-expression:' + project.'springframework.version'
compile 'org.springframework:spring-web:' + project.'springframework.version'
compile 'org.springframework:spring-webmvc:' + project.'springframework.version'
compile 'com.github.stephenc.findbugs:findbugs-annotations:' + project.'stephenc-findbugs.version'
testCompile 'com.github.stefanbirkner:system-rules:' + project.'system-rules.version'
testCompile 'com.google.code.tempus-fugit:tempus-fugit:' + project.'tempus-fugit.version'
testCompile 'com.jayway.awaitility:awaitility:' + project.'awaitility.version'
testCompile 'edu.umd.cs.mtc:multithreadedtc:' + project.'multithreadedtc.version'
testCompile 'eu.codearte.catch-exception:catch-exception:' + project.'catch-exception.version'
testCompile 'eu.codearte.catch-exception:catch-throwable:' + project.'catch-throwable.version'
testCompile 'junit:junit:' + project.'junit.version'
testCompile 'org.assertj:assertj-core:' + project.'assertj-core.version'
testCompile 'org.mockito:mockito-core:' + project.'mockito-core.version'
testCompile 'org.hamcrest:hamcrest-all:' + project.'hamcrest-all.version'
testCompile 'org.jmock:jmock:' + project.'jmock.version'
testCompile 'org.jmock:jmock-junit4:' + project.'jmock.version'
testCompile 'org.jmock:jmock-legacy:' + project.'jmock.version'
testCompile 'pl.pragmatists:JUnitParams:' + project.'JUnitParams.version'
testRuntime 'cglib:cglib:' + project.'cglib.version'
testRuntime 'org.objenesis:objenesis:' + project.'objenesis.version'
testRuntime 'org.ow2.asm:asm:' + project.'asm.version'
}
//This target does not run any tests. Rather, it validates that there are no
//tests that are missing a category annotation
task checkMissedTests(type: Test) {
include '**/*Test.class'
useJUnit {
excludeCategories 'com.gemstone.gemfire.test.junit.categories.UnitTest'
excludeCategories 'com.gemstone.gemfire.test.junit.categories.IntegrationTest'
excludeCategories 'com.gemstone.gemfire.test.junit.categories.DistributedTest'
excludeCategories 'com.gemstone.gemfire.test.junit.categories.PerformanceTest'
excludeCategories 'com.gemstone.gemfire.test.junit.categories.HydraTest'
excludeCategories 'com.gemstone.gemfire.test.junit.categories.ContainerTest'
excludeCategories 'com.gemstone.gemfire.test.junit.categories.UITest'
}
beforeTest { descriptor ->
throw new GradleException("The test " + descriptor.getClassName() + "." + descriptor.getName() + " does not include a junit category.");
}
}
test {
include '**/*Test.class'
useJUnit {
includeCategories 'com.gemstone.gemfire.test.junit.categories.UnitTest'
excludeCategories 'com.gemstone.gemfire.test.junit.categories.IntegrationTest'
excludeCategories 'com.gemstone.gemfire.test.junit.categories.DistributedTest'
excludeCategories 'com.gemstone.gemfire.test.junit.categories.PerformanceTest'
excludeCategories 'com.gemstone.gemfire.test.junit.categories.HydraTest'
excludeCategories 'com.gemstone.gemfire.test.junit.categories.ContainerTest'
excludeCategories 'com.gemstone.gemfire.test.junit.categories.UITest'
}
// run each test in its own vm to avoid interference issues if a test doesn't clean up
// state
//forkEvery 1
doFirst {
writeTestProperties(buildDir, name)
}
}
task integrationTest(type:Test) {
include '**/*Test.class'
exclude '**/*DUnitTest.class'
useJUnit {
excludeCategories 'com.gemstone.gemfire.test.junit.categories.UnitTest'
includeCategories 'com.gemstone.gemfire.test.junit.categories.IntegrationTest'
excludeCategories 'com.gemstone.gemfire.test.junit.categories.DistributedTest'
excludeCategories 'com.gemstone.gemfire.test.junit.categories.PerformanceTest'
excludeCategories 'com.gemstone.gemfire.test.junit.categories.HydraTest'
excludeCategories 'com.gemstone.gemfire.test.junit.categories.ContainerTest'
excludeCategories 'com.gemstone.gemfire.test.junit.categories.UITest'
}
forkEvery 1
doFirst {
writeTestProperties(buildDir, name)
}
}
task uiTest(type:Test) {
include '**/*Test.class'
useJUnit {
excludeCategories 'com.gemstone.gemfire.test.junit.categories.UnitTest'
excludeCategories 'com.gemstone.gemfire.test.junit.categories.IntegrationTest'
excludeCategories 'com.gemstone.gemfire.test.junit.categories.DistributedTest'
excludeCategories 'com.gemstone.gemfire.test.junit.categories.PerformanceTest'
excludeCategories 'com.gemstone.gemfire.test.junit.categories.HydraTest'
excludeCategories 'com.gemstone.gemfire.test.junit.categories.ContainerTest'
includeCategories 'com.gemstone.gemfire.test.junit.categories.UITest'
}
doFirst {
writeTestProperties(buildDir, name)
}
}
task distributedTest(type:Test) {
include '**/*Test.class'
// maxParallelForks = 2
// maxParallelForks = Runtime.runtime.availableProcessors()
useJUnit {
excludeCategories 'com.gemstone.gemfire.test.junit.categories.UnitTest'
excludeCategories 'com.gemstone.gemfire.test.junit.categories.IntegrationTest'
includeCategories 'com.gemstone.gemfire.test.junit.categories.DistributedTest'
excludeCategories 'com.gemstone.gemfire.test.junit.categories.PerformanceTest'
excludeCategories 'com.gemstone.gemfire.test.junit.categories.HydraTest'
excludeCategories 'com.gemstone.gemfire.test.junit.categories.ContainerTest'
excludeCategories 'com.gemstone.gemfire.test.junit.categories.UITest'
}
//I'm hoping this might deal with SOME OOMEs I've seen
forkEvery 30
}
// By proving a file with an arbitrary list of test classes, we can select only those
// tests to run. Activated using -Dcustom.tests=<file> customTest
def customTestList = []
def customTestFile = System.getProperty('custom.tests')
if (customTestFile != null) {
new File(customTestFile).eachLine { customTestList << it }
}
task customTest(type:Test) {
include { x ->
(x.isDirectory() || customTestList.any { y -> x.getName().contains(y) } ) ? true : false
}
forkEvery 30
}
// apply common test configuration
gradle.taskGraph.whenReady( { graph ->
tasks.withType(Test).each { test ->
check.dependsOn test
test.configure {
onlyIf { ! Boolean.getBoolean('skip.tests') }
//force tests to be run every time by
//saying the results are never up to date
outputs.upToDateWhen { false }
def resultsDir = testResultsDir(buildDir, test.name)
workingDir resultsDir.absolutePath
reports.html.destination = file "$buildDir/reports/$name"
testLogging {
exceptionFormat = 'full'
}
maxHeapSize '768m'
jvmArgs = ['-XX:+HeapDumpOnOutOfMemoryError', '-ea']
systemProperty 'gemfire.DEFAULT_MAX_OPLOG_SIZE', '10'
systemProperty 'gemfire.disallowMcastDefaults', 'true'
systemProperty 'jline.terminal', 'jline.UnsupportedTerminal'
def eol = System.getProperty('line.separator')
def progress = new File(resultsDir, "$test.name-progress.txt")
beforeTest { desc ->
def now = new Date().format('yyyy-MM-dd HH:mm:ss.SSS Z')
progress << "$now Starting test $desc.className $desc.name$eol"
}
afterTest { desc, result ->
def now = new Date().format('yyyy-MM-dd HH:mm:ss.SSS Z')
progress << "$now Completed test $desc.className $desc.name with result: ${result.resultType}$eol"
}
doFirst {
resultsDir.deleteDir()
resultsDir.mkdirs()
}
}
}
})
// publishing configuration
apply plugin: 'com.bmuschko.nexus'
extraArchive {
sources = true
javadoc = true
tests = false
}
nexus {
sign = true
repositoryUrl = 'https://repository.apache.org/service/local/staging/deploy/maven2'
snapshotRepositoryUrl = 'https://repository.apache.org/content/repositories/snapshots'
}
modifyPom {
project {
name 'Apache Geode (incubating)'
description 'Apache Geode (incubating) provides a database-like consistency model, reliable transaction processing and a shared-nothing architecture to maintain very low latency performance with high concurrency processing'
url 'http://geode.incubator.apache.org'
scm {
url 'https://git-wip-us.apache.org/repos/asf?p=incubator-geode.git;a=tree'
connection 'scm:https://git-wip-us.apache.org/repos/asf/incubator-geode.git'
developerConnection 'scm:https://git-wip-us.apache.org/repos/asf/incubator-geode.git'
}
licenses {
license {
name 'The Apache Software License, Version 2.0'
url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
}
}
repositories {
repository {
id 'libs-release'
name 'Spring Maven libs-release Repository'
url 'http://repo.spring.io/libs-release'
}
}
}
}
// The nexus plugin reads authentication from ~/.gradle/gradle.properties but the
// jenkins server stores publishing credentials in ~/.m2/settings.xml (maven).
// We match on the expected snapshot repository id.
afterEvaluate {
if (!isReleaseVersion && System.env.USER == 'jenkins') {
def settingsXml = new File(System.getProperty('user.home'), '.m2/settings.xml')
if (settingsXml.exists()) {
def snapshotCreds = new XmlSlurper().parse(settingsXml).servers.server.find { server ->
server.id.text() == 'apache.snapshots.https'
}
if (snapshotCreds != null) {
tasks.uploadArchives.doFirst {
repositories().withType(MavenDeployer).each { repo ->
repo.snapshotRepository.authentication.userName = snapshotCreds.username.text()
repo.snapshotRepository.authentication.password = snapshotCreds.password.text()
}
}
}
}
}
}
// Make precheckin task run all validation tests for checking in code.
task precheckin (dependsOn: [ build, integrationTest, distributedTest ]) {
description 'Run this task before checking in code to validate changes. This task combines the following tasks: build, integrationTest, and distributedTest'
}
check.dependsOn checkMissedTests, rat
combineReports.mustRunAfter check, test, integrationTest, distributedTest, checkMissedTests
build.finalizedBy combineReports
check.finalizedBy combineReports
test.finalizedBy combineReports
integrationTest.finalizedBy combineReports
distributedTest.finalizedBy combineReports
checkMissedTests.finalizedBy combineReports
// Make sure clean task for rootProject runs last
clean.finalizedBy rootProject.clean
}