[K/N] Support running with thread sanitizer in test infra
This commit is contained in:
@@ -90,12 +90,13 @@ To run blackbox compiler tests use:
|
|||||||
| `forceStandalone ` | If `true` then all tests with `// KIND: REGULAR` inside test data file are executed as if they were be with `// KIND: STANDALONE`. The default is `false`. |
|
| `forceStandalone ` | If `true` then all tests with `// KIND: REGULAR` inside test data file are executed as if they were be with `// KIND: STANDALONE`. The default is `false`. |
|
||||||
| `compileOnly ` | If `true` then tests are fully compiled to the executable binary, but not executed afterwards. The default is `false`. |
|
| `compileOnly ` | If `true` then tests are fully compiled to the executable binary, but not executed afterwards. The default is `false`. |
|
||||||
| `optimizationMode` | Compiler optimization mode: `DEBUG` (default), `OPT`, `NO` |
|
| `optimizationMode` | Compiler optimization mode: `DEBUG` (default), `OPT`, `NO` |
|
||||||
| `memoryModel` | The memory model: `LEGACY` or `EXPERIMENTAL` (default) |
|
| `memoryModel` | The memory model: `LEGACY` or `EXPERIMENTAL` (default) |
|
||||||
| `useThreadStateChecker` | If `true` the thread state checker is enabled. The default is `false`.<br/><br/>Note: Thread state checker can be enabled only in combination with `optimizationMode=DEBUG`, `memoryModel=EXPERIMENTAL` and `cacheMode=NO`. |
|
| `useThreadStateChecker` | If `true` the thread state checker is enabled. The default is `false`.<br/><br/>Note: Thread state checker can be enabled only in combination with `optimizationMode=DEBUG`, `memoryModel=EXPERIMENTAL` and `cacheMode=NO`. |
|
||||||
| `gcType` | The type of GC: `UNSPECIFIED` (default), `NOOP`, `STMS`, `CMS`<br/><br/>Note: The GC type can be specified only in combination with `memoryModel=EXPERIMENTAL`. |
|
| `gcType` | The type of GC: `UNSPECIFIED` (default), `NOOP`, `STMS`, `CMS`<br/><br/>Note: The GC type can be specified only in combination with `memoryModel=EXPERIMENTAL`. |
|
||||||
| `gcScheduler` | The type of GC scheduler: `UNSPECIFIED` (default), `DISABLED`, `WITH_TIMER`, `ON_SAFE_POINTS`, `AGGRESSIVE`<br/><br/>Note: The GC scheduler type can be specified only in combination with `memoryModel=EXPERIMENTAL`. |
|
| `gcScheduler` | The type of GC scheduler: `UNSPECIFIED` (default), `DISABLED`, `WITH_TIMER`, `ON_SAFE_POINTS`, `AGGRESSIVE`<br/><br/>Note: The GC scheduler type can be specified only in combination with `memoryModel=EXPERIMENTAL`. |
|
||||||
| `cacheMode` | * `NO`: no caches <br/>* `STATIC_ONLY_DIST` (default): use only caches for libs from the distribution <br/>* `STATIC_EVERYWHERE`: use caches for libs from the distribution and generate caches for all produced KLIBs<br/><br/>Note: Any cache mode that permits using caches can be enabled only when thread state checker is disabled. |
|
| `cacheMode` | * `NO`: no caches <br/>* `STATIC_ONLY_DIST` (default): use only caches for libs from the distribution <br/>* `STATIC_EVERYWHERE`: use caches for libs from the distribution and generate caches for all produced KLIBs<br/><br/>Note: Any cache mode that permits using caches can be enabled only when thread state checker is disabled. |
|
||||||
| `executionTimeout` | Max permitted duration of each individual test execution in milliseconds |
|
| `executionTimeout` | Max permitted duration of each individual test execution in milliseconds |
|
||||||
|
| `sanitizer` | Run tests with sanitizer: `NONE` (default), `THREAD`. |
|
||||||
|
|
||||||
### Target-specific tests
|
### Target-specific tests
|
||||||
|
|
||||||
|
|||||||
@@ -57,7 +57,8 @@ enum class TestProperty(shortName: String) {
|
|||||||
GC_TYPE("gcType"),
|
GC_TYPE("gcType"),
|
||||||
GC_SCHEDULER("gcScheduler"),
|
GC_SCHEDULER("gcScheduler"),
|
||||||
CACHE_MODE("cacheMode"),
|
CACHE_MODE("cacheMode"),
|
||||||
EXECUTION_TIMEOUT("executionTimeout");
|
EXECUTION_TIMEOUT("executionTimeout"),
|
||||||
|
SANITIZER("sanitizer");
|
||||||
|
|
||||||
private val propertyName = "kotlin.internal.native.test.$shortName"
|
private val propertyName = "kotlin.internal.native.test.$shortName"
|
||||||
|
|
||||||
@@ -130,6 +131,7 @@ fun nativeTest(taskName: String, vararg tags: String) = projectTest(
|
|||||||
TestProperty.GC_SCHEDULER.setUpFromGradleProperty(this)
|
TestProperty.GC_SCHEDULER.setUpFromGradleProperty(this)
|
||||||
TestProperty.CACHE_MODE.setUpFromGradleProperty(this)
|
TestProperty.CACHE_MODE.setUpFromGradleProperty(this)
|
||||||
TestProperty.EXECUTION_TIMEOUT.setUpFromGradleProperty(this)
|
TestProperty.EXECUTION_TIMEOUT.setUpFromGradleProperty(this)
|
||||||
|
TestProperty.SANITIZER.setUpFromGradleProperty(this)
|
||||||
|
|
||||||
// Pass the current Gradle task name so test can use it in logging.
|
// Pass the current Gradle task name so test can use it in logging.
|
||||||
environment("GRADLE_TASK_NAME", path)
|
environment("GRADLE_TASK_NAME", path)
|
||||||
|
|||||||
+2
-1
@@ -51,7 +51,8 @@ internal enum class ClassLevelProperty(shortName: String) {
|
|||||||
GC_TYPE("gcType"),
|
GC_TYPE("gcType"),
|
||||||
GC_SCHEDULER("gcScheduler"),
|
GC_SCHEDULER("gcScheduler"),
|
||||||
CACHE_MODE("cacheMode"),
|
CACHE_MODE("cacheMode"),
|
||||||
EXECUTION_TIMEOUT("executionTimeout");
|
EXECUTION_TIMEOUT("executionTimeout"),
|
||||||
|
SANITIZER("sanitizer");
|
||||||
|
|
||||||
internal val propertyName = fullPropertyName(shortName)
|
internal val propertyName = fullPropertyName(shortName)
|
||||||
|
|
||||||
|
|||||||
+8
@@ -152,6 +152,7 @@ private object NativeTestSupport {
|
|||||||
"Thread state checker can be enabled only with debug optimization mode"
|
"Thread state checker can be enabled only with debug optimization mode"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
val sanitizer = computeSanitizer(enforcedProperties)
|
||||||
|
|
||||||
val gcType = computeGCType(enforcedProperties)
|
val gcType = computeGCType(enforcedProperties)
|
||||||
if (gcType != GCType.UNSPECIFIED) {
|
if (gcType != GCType.UNSPECIFIED) {
|
||||||
@@ -178,6 +179,9 @@ private object NativeTestSupport {
|
|||||||
assertEquals(ThreadStateChecker.DISABLED, threadStateChecker) {
|
assertEquals(ThreadStateChecker.DISABLED, threadStateChecker) {
|
||||||
"Thread state checker can not be used with cache"
|
"Thread state checker can not be used with cache"
|
||||||
}
|
}
|
||||||
|
assertEquals(Sanitizer.NONE, sanitizer) {
|
||||||
|
"Sanitizer can not be used with cache"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
output += optimizationMode
|
output += optimizationMode
|
||||||
@@ -186,6 +190,7 @@ private object NativeTestSupport {
|
|||||||
output += gcType
|
output += gcType
|
||||||
output += gcScheduler
|
output += gcScheduler
|
||||||
output += nativeTargets
|
output += nativeTargets
|
||||||
|
output += sanitizer
|
||||||
output += CacheMode::class to cacheMode
|
output += CacheMode::class to cacheMode
|
||||||
output += computeTestMode(enforcedProperties)
|
output += computeTestMode(enforcedProperties)
|
||||||
output += computeForcedStandaloneTestKind(enforcedProperties)
|
output += computeForcedStandaloneTestKind(enforcedProperties)
|
||||||
@@ -211,6 +216,9 @@ private object NativeTestSupport {
|
|||||||
return if (useThreadStateChecker) ThreadStateChecker.ENABLED else ThreadStateChecker.DISABLED
|
return if (useThreadStateChecker) ThreadStateChecker.ENABLED else ThreadStateChecker.DISABLED
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun computeSanitizer(enforcedProperties: EnforcedProperties): Sanitizer =
|
||||||
|
ClassLevelProperty.SANITIZER.readValue(enforcedProperties, Sanitizer.values(), default = Sanitizer.NONE)
|
||||||
|
|
||||||
private fun computeGCType(enforcedProperties: EnforcedProperties): GCType =
|
private fun computeGCType(enforcedProperties: EnforcedProperties): GCType =
|
||||||
ClassLevelProperty.GC_TYPE.readValue(enforcedProperties, GCType.values(), default = GCType.UNSPECIFIED)
|
ClassLevelProperty.GC_TYPE.readValue(enforcedProperties, GCType.values(), default = GCType.UNSPECIFIED)
|
||||||
|
|
||||||
|
|||||||
+4
@@ -119,6 +119,7 @@ internal abstract class SourceBasedCompilation<A : TestCompilationArtifact>(
|
|||||||
optimizationMode: OptimizationMode,
|
optimizationMode: OptimizationMode,
|
||||||
private val memoryModel: MemoryModel,
|
private val memoryModel: MemoryModel,
|
||||||
private val threadStateChecker: ThreadStateChecker,
|
private val threadStateChecker: ThreadStateChecker,
|
||||||
|
private val sanitizer: Sanitizer,
|
||||||
private val gcType: GCType,
|
private val gcType: GCType,
|
||||||
private val gcScheduler: GCScheduler,
|
private val gcScheduler: GCScheduler,
|
||||||
freeCompilerArgs: TestCompilerArgs,
|
freeCompilerArgs: TestCompilerArgs,
|
||||||
@@ -138,6 +139,7 @@ internal abstract class SourceBasedCompilation<A : TestCompilationArtifact>(
|
|||||||
add("-repo", home.librariesDir.path)
|
add("-repo", home.librariesDir.path)
|
||||||
memoryModel.compilerFlags?.let { compilerFlags -> add(compilerFlags) }
|
memoryModel.compilerFlags?.let { compilerFlags -> add(compilerFlags) }
|
||||||
threadStateChecker.compilerFlag?.let { compilerFlag -> add(compilerFlag) }
|
threadStateChecker.compilerFlag?.let { compilerFlag -> add(compilerFlag) }
|
||||||
|
sanitizer.compilerFlag?.let { compilerFlag -> add(compilerFlag) }
|
||||||
gcType.compilerFlag?.let { compilerFlag -> add(compilerFlag) }
|
gcType.compilerFlag?.let { compilerFlag -> add(compilerFlag) }
|
||||||
gcScheduler.compilerFlag?.let { compilerFlag -> add(compilerFlag) }
|
gcScheduler.compilerFlag?.let { compilerFlag -> add(compilerFlag) }
|
||||||
}
|
}
|
||||||
@@ -164,6 +166,7 @@ internal class LibraryCompilation(
|
|||||||
optimizationMode = settings.get(),
|
optimizationMode = settings.get(),
|
||||||
memoryModel = settings.get(),
|
memoryModel = settings.get(),
|
||||||
threadStateChecker = settings.get(),
|
threadStateChecker = settings.get(),
|
||||||
|
sanitizer = settings.get(),
|
||||||
gcType = settings.get(),
|
gcType = settings.get(),
|
||||||
gcScheduler = settings.get(),
|
gcScheduler = settings.get(),
|
||||||
freeCompilerArgs = freeCompilerArgs,
|
freeCompilerArgs = freeCompilerArgs,
|
||||||
@@ -196,6 +199,7 @@ internal class ExecutableCompilation(
|
|||||||
optimizationMode = settings.get(),
|
optimizationMode = settings.get(),
|
||||||
memoryModel = settings.get(),
|
memoryModel = settings.get(),
|
||||||
threadStateChecker = settings.get(),
|
threadStateChecker = settings.get(),
|
||||||
|
sanitizer = settings.get(),
|
||||||
gcType = settings.get(),
|
gcType = settings.get(),
|
||||||
gcScheduler = settings.get(),
|
gcScheduler = settings.get(),
|
||||||
freeCompilerArgs = freeCompilerArgs,
|
freeCompilerArgs = freeCompilerArgs,
|
||||||
|
|||||||
+11
-1
@@ -101,7 +101,7 @@ internal enum class MemoryModel(val compilerFlags: List<String>?) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thread state checked. Can be applied only with [MemoryModel.EXPERIMENTAL] and [OptimizationMode.DEBUG].
|
* Thread state checked. Can be applied only with [MemoryModel.EXPERIMENTAL], [OptimizationMode.DEBUG], [CacheMode.WithoutCache].
|
||||||
*/
|
*/
|
||||||
internal enum class ThreadStateChecker(val compilerFlag: String?) {
|
internal enum class ThreadStateChecker(val compilerFlag: String?) {
|
||||||
DISABLED(null),
|
DISABLED(null),
|
||||||
@@ -110,6 +110,16 @@ internal enum class ThreadStateChecker(val compilerFlag: String?) {
|
|||||||
override fun toString() = compilerFlag?.let { "($it)" }.orEmpty()
|
override fun toString() = compilerFlag?.let { "($it)" }.orEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type of sanitizer. Can be applied only with [CacheMode.WithoutCache]
|
||||||
|
*/
|
||||||
|
internal enum class Sanitizer(val compilerFlag: String?) {
|
||||||
|
NONE(null),
|
||||||
|
THREAD("-Xbinary=sanitizer=thread");
|
||||||
|
|
||||||
|
override fun toString() = compilerFlag?.let { "($it)" }.orEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Garbage collector type. Can be applied only with [MemoryModel.EXPERIMENTAL].
|
* Garbage collector type. Can be applied only with [MemoryModel.EXPERIMENTAL].
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user