2020-01-27 12:05:34 -05:00
/ *
* 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 .
* /
2019-12-06 05:55:53 -05:00
//
2019-12-02 09:34:57 -05:00
// Configure test randomization seeds and derived test properties.
2019-12-06 05:55:53 -05:00
//
2019-12-06 11:08:14 -05:00
import java.nio.file.*
2019-12-06 05:55:53 -05:00
import com.carrotsearch.randomizedtesting.SeedUtils
import com.carrotsearch.randomizedtesting.generators.RandomPicks
2020-09-30 03:49:52 -04:00
import org.apache.tools.ant.types.Commandline
2019-12-06 05:55:53 -05:00
buildscript {
repositories {
mavenCentral ( )
}
dependencies {
2024-06-17 03:49:21 -04:00
classpath deps . randomizedtesting . runner
2019-12-06 05:55:53 -05:00
}
}
2019-12-02 09:34:57 -05:00
2020-08-31 09:35:14 -04:00
def resources = scriptResources ( buildscript )
2019-12-02 09:34:57 -05:00
// Pick the "root" seed from which everything else is derived.
configure ( rootProject ) {
ext {
rootSeed = propertyOrDefault ( 'tests.seed' , String . format ( "%08X" , new Random ( ) . nextLong ( ) ) )
2020-08-18 03:28:50 -04:00
rootSeedUserProvided = ( propertyOrDefault ( 'tests.seed' , null ) ! = null )
2019-12-06 05:55:53 -05:00
rootSeedLong = SeedUtils . parseSeedChain ( rootSeed ) [ 0 ]
projectSeedLong = rootSeedLong ^ project . path . hashCode ( )
2019-12-02 09:34:57 -05:00
}
task randomizationInfo ( ) {
doFirst {
logger . lifecycle ( "Running tests with randomization seed: tests.seed=${rootSeed}" )
}
}
}
// Any test task will trigger display of randomization settings.
allprojects {
tasks . withType ( Test ) { task - >
task . dependsOn rootProject . randomizationInfo
}
}
2019-12-06 05:55:53 -05:00
// Configure test property defaults and their descriptions.
2019-12-02 09:34:57 -05:00
allprojects {
2019-12-06 05:55:53 -05:00
plugins . withType ( JavaPlugin ) {
2024-08-30 06:36:56 -04:00
project . ext {
2024-05-09 06:00:51 -04:00
String randomVectorSize = RandomPicks . randomFrom ( new Random ( projectSeedLong ) , [ "default" , "128" , "256" , "512" ] )
2020-08-31 06:20:30 -04:00
testOptions + = [
2019-12-06 05:55:53 -05:00
// seed, repetition and amplification.
2020-08-31 06:20:30 -04:00
[ propName: 'tests.seed' , value: { - > rootSeed } , description: "Sets the master randomization seed." ] ,
2020-08-18 03:28:50 -04:00
[ propName: 'tests.iters' , value: null , description: "Duplicate (re-run) each test case N times." ] ,
2023-11-03 12:05:17 -04:00
[ propName: 'tests.multiplier' , value: null , description: "Value multiplier for randomized tests." ] ,
2019-12-06 05:55:53 -05:00
[ propName: 'tests.maxfailures' , value: null , description: "Skip tests after a given number of failures." ] ,
[ propName: 'tests.timeoutSuite' , value: null , description: "Timeout (in millis) for an entire suite." ] ,
2019-12-06 11:08:14 -05:00
[ propName: 'tests.failfast' , value: "false" , description: "Stop the build early on failure." , buildOnly: true ] ,
2019-12-06 05:55:53 -05:00
// asserts, debug output.
[ propName: 'tests.asserts' , value: "true" , description: "Enables or disables assertions mode." ] ,
2019-12-08 12:45:41 -05:00
[ propName: 'tests.infostream' , value: false , description: "Enables or disables infostream logs." ] ,
2020-08-31 06:20:30 -04:00
[ propName: 'tests.leaveTemporary' , value: false , description: "Leave temporary directories after tests complete." ] ,
2019-12-16 09:56:29 -05:00
[ propName: 'tests.useSecurityManager' , value: true , description: "Control security manager in tests." , buildOnly: true ] ,
2019-12-06 05:55:53 -05:00
// component randomization
[ propName: 'tests.codec' , value: "random" , description: "Sets the codec tests should run with." ] ,
[ propName: 'tests.directory' , value: "random" , description: "Sets the Directory implementation tests should run with." ] ,
[ propName: 'tests.postingsformat' , value: "random" , description: "Sets the postings format tests should run with." ] ,
[ propName: 'tests.docvaluesformat' , value: "random" , description: "Sets the doc values format tests should run with." ] ,
[ propName: 'tests.locale' , value: "random" , description: "Sets the default locale tests should run with." ] ,
[ propName: 'tests.timezone' , value: "random" , description: "Sets the default time zone tests should run with." ] ,
// filtering
[ propName: 'tests.filter' , value: null , description: "Applies a test filter (see :helpTests)." ] ,
[ propName: 'tests.nightly' , value: false , description: "Enables or disables @Nightly tests." ] ,
[ propName: 'tests.weekly' , value: false , description: "Enables or disables @Weekly tests." ] ,
[ propName: 'tests.monster' , value: false , description: "Enables or disables @Monster tests." ] ,
[ propName: 'tests.awaitsfix' , value: null , description: "Enables or disables @AwaitsFix tests." ] ,
2022-05-17 20:26:06 -04:00
[ propName: 'tests.gui' ,
value: { - >
return rootProject . ext . isCIBuild
} ,
description: "Enables or disables @RequiresGUI tests." ] ,
2020-08-31 06:20:30 -04:00
[ propName: 'tests.file.encoding' ,
2022-05-17 20:26:06 -04:00
value: { - >
RandomPicks . randomFrom ( new Random ( projectSeedLong ) , [ "US-ASCII" , "ISO-8859-1" , "UTF-8" ] )
} ,
description: "Sets the default file.encoding on test JVM." , buildOnly: true ] ,
2021-03-22 07:22:39 -04:00
// Test data file used.
2019-12-06 05:55:53 -05:00
[ propName: 'tests.linedocsfile' , value: 'europarl.lines.txt.gz' , description: "Test data file path." ] ,
// miscellaneous; some of them very weird.
2019-12-06 07:05:10 -05:00
[ propName: 'tests.LUCENE_VERSION' , value: baseVersion , description: "Base Lucene version." ] ,
2019-12-06 05:55:53 -05:00
[ propName: 'tests.bwcdir' , value: null , description: "Data for backward-compatibility indexes." ] ,
2023-10-14 19:51:59 -04:00
// vectorization related
[ propName: 'tests.vectorsize' ,
2024-05-09 06:00:51 -04:00
value: { - > testsDefaultVectorizationRequested ( ) ? 'default' : randomVectorSize } ,
description: "Sets preferred vector size in bits." ] ,
[ propName: 'tests.forceintegervectors' ,
value: { - > testsDefaultVectorizationRequested ( ) ? false : ( randomVectorSize ! = 'default' ) } ,
description: "Forces use of integer vectors even when slow." ] ,
[ propName: 'tests.defaultvectorization' , value: false ,
description: "Uses defaults for running tests with correct JVM settings to test Panama vectorization (tests.jvmargs, tests.vectorsize, tests.forceintegervectors)." ] ,
2019-12-06 05:55:53 -05:00
]
}
}
}
// Resolve test option values after all evaluation is complete.
allprojects {
plugins . withType ( JavaPlugin ) {
2024-03-08 02:10:49 -05:00
configurations {
secManagerExclusions
}
dependencies {
2024-06-17 03:49:21 -04:00
secManagerExclusions ( deps . randomizedtesting . runner , {
2024-03-08 02:10:49 -05:00
exclude group: "junit"
} )
2024-06-17 03:49:21 -04:00
secManagerExclusions ( deps . junit , {
2024-03-08 02:10:49 -05:00
exclude group: "org.hamcrest"
} )
}
2019-12-06 05:55:53 -05:00
afterEvaluate {
2024-08-30 06:36:56 -04:00
project . ext . testOptionsResolved = testOptions . findAll { opt - >
2019-12-06 05:55:53 -05:00
propertyOrDefault ( opt . propName , opt . value ) ! = null
} . collectEntries { opt - >
2020-08-31 06:20:30 -04:00
[ ( opt . propName ) : Objects . toString ( resolvedTestOption ( opt . propName ) ) ]
2020-01-08 06:20:09 -05:00
}
// Compute the "reproduce with" string.
2024-08-30 06:36:56 -04:00
project . ext . testOptionsForReproduceLine = testOptions . findAll { opt - >
2020-08-31 06:20:30 -04:00
if ( opt [ "includeInReproLine" ] = = false ) {
return false
}
2020-01-08 06:20:09 -05:00
def defValue = Objects . toString ( opt . value , null )
def value = testOptionsResolved [ opt . propName ]
return defValue ! = value
} . collect { opt - >
2020-09-30 03:49:52 -04:00
Commandline . quoteArgument ( "-P" + opt . propName + "=" + testOptionsResolved [ opt . propName ] )
2020-01-08 06:20:09 -05:00
} . join ( " " )
2019-12-06 05:55:53 -05:00
// leaving temporary folder option has multiple aliases...
if ( [
"tests.leaveTemporary" ,
"tests.leavetemporary" ,
"tests.leavetmpdir" ,
] . find { prop - >
2020-08-31 06:20:30 -04:00
def v = Boolean . parseBoolean ( propertyOrDefault ( prop , "false" ) )
if ( v ) {
logger . lifecycle ( "Update your code to use the official 'tests.leaveTemporary' option (you used '${prop}')." )
}
return v
2019-12-06 05:55:53 -05:00
} ) {
2019-12-06 11:08:14 -05:00
testOptionsResolved [ 'tests.leaveTemporary' ] = "true"
2019-12-06 05:55:53 -05:00
}
// Append resolved test properties to the test task.
2024-03-08 02:10:49 -05:00
tasks . withType ( Test ) { Test task - >
2020-08-31 06:20:30 -04:00
// TODO: we could remove some options that are only relevant to the build environment
// and not the test JVM itself.
2019-12-06 05:55:53 -05:00
systemProperties testOptionsResolved
2024-05-09 06:00:51 -04:00
jvmArgs Commandline . translateCommandline ( testOptionsResolved [ 'tests.jvmargs' ] )
2019-12-06 05:55:53 -05:00
if ( Boolean . parseBoolean ( testOptionsResolved [ 'tests.asserts' ] ) ) {
jvmArgs ( "-ea" , "-esa" )
} else {
enableAssertions = false
}
2019-12-06 11:08:14 -05:00
if ( Boolean . parseBoolean ( testOptionsResolved [ "tests.failfast" ] ) ) {
failFast true
}
// Enable security manager, if requested. We could move the selection of security manager and security policy
// to each project's build/ configuration but it seems compact enough to keep it here for now.
2024-03-08 02:10:49 -05:00
def securityArgumentProvider = new SecurityArgumentProvider ( )
securityArgumentProvider . commonDir = project ( ":lucene" ) . layout . projectDirectory
securityArgumentProvider . otherProperties = project . objects . mapProperty ( String , String )
2019-12-06 11:08:14 -05:00
if ( Boolean . parseBoolean ( testOptionsResolved [ "tests.useSecurityManager" ] ) ) {
2021-12-19 02:51:13 -05:00
if ( project . path . endsWith ( ".tests" ) ) {
// LUCENE-10301: for now, do not use the security manager for modular tests (test framework is not available).
2019-12-06 11:08:14 -05:00
} else if ( project . path . startsWith ( ":lucene" ) ) {
2021-12-21 14:30:45 -05:00
systemProperty 'java.security.manager' , "org.apache.lucene.tests.util.TestSecurityManager"
2023-03-06 13:17:37 -05:00
securityArgumentProvider . javaSecurityPolicy = layout . projectDirectory . file ( "${resources}/policies/tests.policy" )
2019-12-06 11:08:14 -05:00
}
2023-03-06 13:17:37 -05:00
jvmArgumentProviders . add ( securityArgumentProvider )
2019-12-06 11:08:14 -05:00
def gradleUserHome = project . gradle . getGradleUserHomeDir ( )
systemProperty 'gradle.lib.dir' , Paths . get ( project . class . location . toURI ( ) ) . parent . toAbsolutePath ( ) . toString ( ) . replace ( '\\' , '/' )
systemProperty 'gradle.worker.jar' , Paths . get ( "${gradleUserHome}/caches/${gradle.gradleVersion}/workerMain/gradle-worker.jar" ) . toAbsolutePath ( ) . toString ( )
systemProperty 'gradle.user.home' , gradleUserHome . toPath ( ) . toAbsolutePath ( ) . toString ( )
2024-03-08 02:10:49 -05:00
securityArgumentProvider . otherProperties . put ( "randomizedtesting.jar" , project . provider { - >
return configurations . secManagerExclusions . resolve ( ) . find { it . name . startsWith ( "randomizedtesting-runner-" ) } . absolutePath
} )
securityArgumentProvider . otherProperties . put ( "junit.jar" , project . provider { - >
return configurations . secManagerExclusions . resolve ( ) . find { it . name . startsWith ( "junit-" ) } . absolutePath
} )
securityArgumentProvider . otherProperties . put ( "lucene.test.framework" , project ( ":lucene:test-framework" ) . layout . buildDirectory . get ( ) . asFile . absolutePath )
2019-12-06 11:08:14 -05:00
}
2019-12-06 05:55:53 -05:00
doFirst {
logger . debug ( "Will use test opts:\n" + testOptionsResolved . collect { k , v - > "${k}: ${v}" } . sort ( ) . join ( "\n" ) )
}
2019-12-02 09:34:57 -05:00
}
}
}
}
2019-12-06 05:55:53 -05:00
// Add a helper task to display resolved test property values with their defaults
// and descriptions.
allprojects {
plugins . withType ( JavaPlugin ) {
2019-12-08 12:45:41 -05:00
task testOpts ( ) {
2019-12-06 05:55:53 -05:00
group = 'Help (developer guides and hints)'
description = "Display values of randomization settings for a given seed"
doFirst {
println "Test options for project ${project.path} and seed \"${rootSeed}\":"
testOptions . sort { a , b - > a . propName . compareTo ( b . propName ) } . each { opt - >
2020-08-31 06:20:30 -04:00
def defValue
def computedValue = false
if ( opt . value instanceof Closure ) {
defValue = Objects . toString ( opt . value ( ) , null )
computedValue = true
} else {
defValue = Objects . toString ( opt . value , null )
}
2019-12-06 05:55:53 -05:00
def value = testOptionsResolved [ opt . propName ]
println String . format ( Locale . ROOT ,
2020-08-31 06:20:30 -04:00
"%s%-24s = %-8s # %s" ,
( defValue ! = value ? "! " : computedValue ? "C " : " " ) ,
2019-12-06 05:55:53 -05:00
opt . propName ,
value ,
2020-08-31 06:20:30 -04:00
( computedValue ? "(!= default: computed) " : ( defValue ! = value ? "(!= default: ${defValue}) " : "" ) ) + opt . description )
2019-12-06 05:55:53 -05:00
}
}
}
}
}
2023-03-06 13:17:37 -05:00
class SecurityArgumentProvider implements CommandLineArgumentProvider {
@Internal
Directory commonDir
@InputFile
@Optional
@PathSensitive ( PathSensitivity . RELATIVE )
RegularFile javaSecurityPolicy
2024-03-08 02:10:49 -05:00
@Input
MapProperty < String , String > otherProperties
2023-03-06 13:17:37 -05:00
@Override
Iterable < String > asArguments ( ) {
def args = [ "-Dcommon.dir=${commonDir.getAsFile()}" ]
if ( javaSecurityPolicy ) {
args . add ( "-Djava.security.policy=${javaSecurityPolicy.getAsFile()}" )
}
2024-03-08 02:10:49 -05:00
otherProperties . getOrElse ( Map . of ( ) ) . forEach { key , value - >
args . add ( "-D${key}=${value}" )
}
2023-03-06 13:17:37 -05:00
return args
}
}