Skip to content

Commit 560c245

Browse files
author
Rustam Sadykov
committed
add monitoring settings
1 parent 1e730a2 commit 560c245

File tree

7 files changed

+139
-67
lines changed

7 files changed

+139
-67
lines changed

.github/workflows/night-statistics-monitoring.yml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ on:
55
- cron: '0 0 * * *'
66

77
env:
8-
run_tries: 3
9-
run_timeout_minutes: 20
8+
monitoring_properties: monitoring/monitoring.properties
109
output_stats: stats.json
1110
history_file: monitoring/history.json
1211
coverage_graph_file: monitoring/coverage_graph.png
@@ -38,8 +37,10 @@ jobs:
3837
- name: Build and run monitoring UTBot Java
3938
run: |
4039
gradle :utbot-junit-contest:monitoringJar
41-
java -jar utbot-junit-contest/build/libs/monitoring.jar \
42-
$output_stats $run_tries $run_timeout_minutes
40+
java -jar \
41+
-Dutbot.monitoring.settings.path=$monitoring_properties \
42+
utbot-junit-contest/build/libs/monitoring.jar \
43+
$output_stats
4344
4445
- name: Update history and render graphs
4546
run: |

docs/NightStatisticsMonitoring.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,15 @@ Thus, we will do it every night when no one makes changes.
1414
### Collecting statistics
1515
Collecting statistics StatisticsMonitoring.kt based on ContestEstimator.kt
1616
that runs testcase generation on projects, then compile generated tests.
17-
We run it several times. Input arguments: `<output json> <run tries> <run timeout min>`.
17+
We run it several times. Input arguments: `<output json>`.
18+
1819
More about statistic: Statistics.kt.
1920

21+
More about monitoring settings: MonitoringSettings.kt
22+
2023
Example input:
2124
```
22-
stats.json 3 20
25+
stats.json
2326
```
2427
Example output:
2528
```json

monitoring/monitoring.properties

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
timeLimitPerClass=20
2+
runTries=3
3+
runTimeoutMinutes=20
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package org.utbot.common
2+
3+
import java.io.FileInputStream
4+
import java.io.IOException
5+
import java.util.*
6+
import mu.KLogger
7+
import org.utbot.common.PathUtil.toPath
8+
import kotlin.properties.PropertyDelegateProvider
9+
import kotlin.reflect.KProperty
10+
11+
abstract class AbstractSettings(
12+
private val logger: KLogger,
13+
defaultKeyForSettingsPath: String,
14+
defaultSettingsPath: String? = null
15+
) {
16+
protected val properties = Properties().also { props ->
17+
val settingsPath = System.getProperty(defaultKeyForSettingsPath) ?: defaultSettingsPath
18+
val settingsPathFile = settingsPath?.toPath()?.toFile()
19+
if (settingsPathFile?.exists() == true) {
20+
try {
21+
FileInputStream(settingsPathFile).use { reader ->
22+
props.load(reader)
23+
}
24+
} catch (e: IOException) {
25+
logger.info(e) { e.message }
26+
}
27+
}
28+
}
29+
30+
protected val settingsValues: MutableMap<KProperty<*>, Any?> = mutableMapOf()
31+
32+
inner class SettingDelegate<T>(val property: KProperty<*>, val initializer: () -> T) {
33+
private var value = initializer()
34+
35+
init {
36+
updateSettingValue()
37+
}
38+
39+
operator fun getValue(thisRef: Any?, property: KProperty<*>): T = value
40+
41+
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
42+
this.value = value
43+
updateSettingValue()
44+
}
45+
46+
private fun updateSettingValue() {
47+
settingsValues[property] = value
48+
}
49+
}
50+
51+
protected fun <T> getProperty(
52+
defaultValue: T,
53+
converter: (String) -> T
54+
): PropertyDelegateProvider<Any?, SettingDelegate<T>> {
55+
return PropertyDelegateProvider { _, property ->
56+
SettingDelegate(property) {
57+
try {
58+
properties.getProperty(property.name)?.let(converter) ?: defaultValue
59+
} catch (e: Throwable) {
60+
logger.info(e) { e.message }
61+
defaultValue
62+
}
63+
}
64+
}
65+
}
66+
67+
protected fun getBooleanProperty(defaultValue: Boolean) = getProperty(defaultValue, String::toBoolean)
68+
protected fun getIntProperty(defaultValue: Int) = getProperty(defaultValue, String::toInt)
69+
protected fun getLongProperty(defaultValue: Long) = getProperty(defaultValue, String::toLong)
70+
protected fun getStringProperty(defaultValue: String) = getProperty(defaultValue) { it }
71+
protected inline fun <reified T : Enum<T>> getEnumProperty(defaultValue: T) =
72+
getProperty(defaultValue) { enumValueOf(it) }
73+
74+
override fun toString(): String =
75+
settingsValues
76+
.mapKeys { it.key.name }
77+
.entries
78+
.sortedBy { it.key }
79+
.joinToString(separator = System.lineSeparator()) { "\t${it.key}=${it.value}" }
80+
}

utbot-framework-api/src/main/kotlin/org/utbot/framework/UtSettings.kt

Lines changed: 4 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
package org.utbot.framework
22

33
import mu.KotlinLogging
4-
import org.utbot.common.PathUtil.toPath
5-
import java.io.FileInputStream
6-
import java.io.IOException
7-
import java.util.Properties
8-
import kotlin.properties.PropertyDelegateProvider
4+
import org.utbot.common.AbstractSettings
95
import kotlin.reflect.KProperty
106

117
private val logger = KotlinLogging.logger {}
@@ -50,43 +46,9 @@ internal class SettingDelegate<T>(val property: KProperty<*>, val initializer: (
5046
*/
5147
const val DEFAULT_CONCRETE_EXECUTION_TIMEOUT_IN_CHILD_PROCESS_MS = 1000L
5248

53-
object UtSettings {
54-
private val properties = Properties().also { props ->
55-
val settingsPath = System.getProperty(defaultKeyForSettingsPath) ?: defaultSettingsPath
56-
val settingsPathFile = settingsPath.toPath().toFile()
57-
if (settingsPathFile.exists()) {
58-
try {
59-
FileInputStream(settingsPathFile).use { reader ->
60-
props.load(reader)
61-
}
62-
} catch (e: IOException) {
63-
logger.info(e) { e.message }
64-
}
65-
}
66-
}
67-
68-
private fun <T> getProperty(
69-
defaultValue: T,
70-
converter: (String) -> T
71-
): PropertyDelegateProvider<UtSettings, SettingDelegate<T>> {
72-
return PropertyDelegateProvider { _, property ->
73-
SettingDelegate(property) {
74-
try {
75-
properties.getProperty(property.name)?.let(converter) ?: defaultValue
76-
} catch (e: Throwable) {
77-
logger.info(e) { e.message }
78-
defaultValue
79-
}
80-
}
81-
}
82-
}
83-
84-
private fun getBooleanProperty(defaultValue: Boolean) = getProperty(defaultValue, String::toBoolean)
85-
private fun getIntProperty(defaultValue: Int) = getProperty(defaultValue, String::toInt)
86-
private fun getLongProperty(defaultValue: Long) = getProperty(defaultValue, String::toLong)
87-
private fun getStringProperty(defaultValue: String) = getProperty(defaultValue) { it }
88-
private inline fun <reified T : Enum<T>> getEnumProperty(defaultValue: T) =
89-
getProperty(defaultValue) { enumValueOf(it) }
49+
object UtSettings : AbstractSettings(
50+
logger, defaultKeyForSettingsPath, defaultSettingsPath
51+
) {
9052

9153
/**
9254
* Setting to disable coroutines debug explicitly.
@@ -388,13 +350,6 @@ object UtSettings {
388350
* Flag that indicates whether tests for synthetic methods (values, valueOf in enums) should be generated, or not
389351
*/
390352
var skipTestGenerationForSyntheticMethods by getBooleanProperty(true)
391-
392-
override fun toString(): String =
393-
settingsValues
394-
.mapKeys { it.key.name }
395-
.entries
396-
.sortedBy { it.key }
397-
.joinToString(separator = System.lineSeparator()) { "\t${it.key}=${it.value}" }
398353
}
399354

400355
/**
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package org.utbot.monitoring
2+
3+
import mu.KotlinLogging
4+
import org.utbot.common.AbstractSettings
5+
6+
7+
private val logger = KotlinLogging.logger {}
8+
9+
private const val defaultKeyForSettingsPath = "utbot.monitoring.settings.path"
10+
11+
object MonitoringSettings : AbstractSettings(
12+
logger, defaultKeyForSettingsPath
13+
) {
14+
/**
15+
* Test generation for one class timeout.
16+
*/
17+
val timeLimitPerClass by getIntProperty(20)
18+
19+
/**
20+
* Bound of classes for generation.
21+
*/
22+
val processedClassesThreshold by getIntProperty(9999)
23+
24+
/**
25+
* Number of running test generation.
26+
*/
27+
val runTries by getIntProperty(1)
28+
29+
/**
30+
* One running generation for all projects timeout in minutes.
31+
*/
32+
val runTimeoutMinutes by getIntProperty(180)
33+
}

utbot-junit-contest/src/main/kotlin/org/utbot/monitoring/StatisticsMonitoring.kt

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import org.utbot.contest.GlobalStats
1111
import org.utbot.contest.Paths
1212
import org.utbot.contest.Tool
1313
import org.utbot.contest.runEstimator
14-
import org.utbot.contest.toText
1514
import org.utbot.framework.JdkPathService
1615
import org.utbot.instrumentation.ConcreteExecutor
1716
import kotlin.system.exitProcess
@@ -20,22 +19,20 @@ private val javaHome = System.getenv("JAVA_HOME")
2019
private val logger = KotlinLogging.logger {}
2120

2221
fun main(args: Array<String>) {
22+
logger.info { "Monitoring Settings:\n$MonitoringSettings" }
23+
2324
val methodFilter: String?
2425
val projectFilter: List<String>?
25-
val processedClassesThreshold = 9999
26+
val processedClassesThreshold = MonitoringSettings.processedClassesThreshold
2627
val tools: List<Tool> = listOf(Tool.UtBot)
27-
val timeLimit = 20
28-
29-
require(args.size == 3) {
30-
"Wrong arguments: <output json> <run tries> <run timeout min> expected, but got: ${args.toText()}"
31-
}
28+
val timeLimit = MonitoringSettings.timeLimitPerClass
3229

3330
projectFilter = listOf("guava")
3431
methodFilter = null
3532

36-
val outputFile = File(args[0])
37-
val runTries = args[1].toInt()
38-
val runTimeout = TimeUnit.MINUTES.toMillis(args[2].toLong())
33+
val outputFile = args.getOrNull(0)?.let { File(it) }
34+
val runTries = MonitoringSettings.runTries
35+
val runTimeout = TimeUnit.MINUTES.toMillis(MonitoringSettings.runTimeoutMinutes.toLong())
3936

4037
val estimatorArgs: Array<String> = arrayOf(
4138
Paths.classesLists,
@@ -51,7 +48,7 @@ fun main(args: Array<String>) {
5148
val executor = ThreadBasedExecutor()
5249

5350
repeat(runTries) { idx ->
54-
logger.info().bracket("Run UTBot try number $idx") {
51+
logger.info().bracket("Run UTBot try number ${idx + 1}") {
5552

5653
executor.invokeWithTimeout(runTimeout) {
5754
runEstimator(estimatorArgs, methodFilter, projectFilter, processedClassesThreshold, tools)
@@ -69,7 +66,7 @@ fun main(args: Array<String>) {
6966
if (statistics.isEmpty())
7067
exitProcess(1)
7168

72-
outputFile.writeText(statistics.jsonString())
69+
outputFile?.writeText(statistics.jsonString())
7370
}
7471

7572
private fun StringBuilder.tab(tabs: Int) {

0 commit comments

Comments
 (0)