Skip to content

Commit d47c9ac

Browse files
committed
feat(test-utils): Stay closer to upstream SystemEnvironmentExtensions
In particular, stick to a configurable `OverrideMode` to be able to share this with ORT Server which depends on that feature. Signed-off-by: Sebastian Schuberth <[email protected]>
1 parent 87c075d commit d47c9ac

File tree

3 files changed

+46
-6
lines changed

3 files changed

+46
-6
lines changed

gradle/libs.versions.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ jsonSchemaValidator = { module = "com.networknt:json-schema-validator", version.
129129
kotest-assertions-core = { module = "io.kotest:kotest-assertions-core", version.ref = "kotest" }
130130
kotest-assertions-json = { module = "io.kotest:kotest-assertions-json", version.ref = "kotest" }
131131
kotest-assertions-table = { module = "io.kotest:kotest-assertions-table", version.ref = "kotest" }
132+
kotest-extensions = { module = "io.kotest:kotest-extensions", version.ref = "kotest" }
132133
kotest-extensions-junitXml = { module = "io.kotest:kotest-extensions-junitxml", version.ref = "kotest" }
133134
kotest-framework-datatest = { module = "io.kotest:kotest-framework-datatest", version.ref = "kotest" }
134135
kotest-framework-engine = { module = "io.kotest:kotest-framework-engine", version.ref = "kotest" }

utils/test/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ dependencies {
2727
api(projects.plugins.versionControlSystems.gitVersionControlSystem)
2828

2929
api(libs.kotest.assertions.core)
30+
api(libs.kotest.extensions)
3031
api(libs.logbackClassic) {
3132
because("Transitively export this to consumers so they do not have to declare a logger implementation.")
3233
}

utils/test/src/main/kotlin/SystemEnvironmentExtensions.kt

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,49 @@
2323

2424
package org.ossreviewtoolkit.utils.test
2525

26+
import io.kotest.extensions.system.OverrideMode
27+
import io.kotest.extensions.system.OverrideMode.SetOrError
28+
2629
import java.lang.reflect.Field
2730

31+
/**
32+
* Modifies System Environment with chosen key and value
33+
*
34+
* This is a helper function for code that uses Environment Variables. It changes the specific [key] from [System.getenv]
35+
* with the specified [value], only during the execution of [block].
36+
*
37+
* To do this, this function uses a trick that makes the System Environment editable, and changes [key]. Any previous
38+
* environment (anything not overridden) will also be in the environment. If the chosen key is in the environment,
39+
* it will be changed according to [mode]. If the chosen key is not in the environment, it will be included.
40+
*
41+
* After the execution of [block], the environment is set to what it was before.
42+
*
43+
* **ATTENTION**: This code is susceptible to race conditions. If you attempt to change the environment while it was
44+
* already changed, the result is inconsistent, as the System Environment Map is a single map.
45+
*/
46+
inline fun <T> withEnvironment(key: String, value: String?, mode: OverrideMode = SetOrError, block: () -> T): T {
47+
return withEnvironment(key to value, mode, block)
48+
}
49+
50+
/**
51+
* Modifies System Environment with chosen key and value
52+
*
53+
* This is a helper function for code that uses Environment Variables. It changes the specific key from [System.getenv]
54+
* with the specified value, only during the execution of [block].
55+
*
56+
* To do this, this function uses a trick that makes the System Environment editable, and changes key. Any previous
57+
* environment (anything not overridden) will also be in the environment. If the chosen key is in the environment,
58+
* it will be changed according to [mode]. If the chosen key is not in the environment, it will be included.
59+
*
60+
* After the execution of [block], the environment is set to what it was before.
61+
*
62+
* **ATTENTION**: This code is susceptible to race conditions. If you attempt to change the environment while it was
63+
* already changed, the result is inconsistent, as the System Environment Map is a single map.
64+
*/
65+
inline fun <T> withEnvironment(environment: Pair<String, String?>, mode: OverrideMode = SetOrError, block: () -> T): T {
66+
return withEnvironment(mapOf(environment), mode, block)
67+
}
68+
2869
/**
2970
* Modifies System Environment with chosen keys and values
3071
*
@@ -33,22 +74,22 @@ import java.lang.reflect.Field
3374
*
3475
* To do this, this function uses a trick that makes the System Environment editable, and changes key. Any previous
3576
* environment (anything not overridden) will also be in the environment. If the chosen key is in the environment,
36-
* it will be overridden. If the chosen key is not in the environment, it will be included.
77+
* it will be changed according to [mode]. If the chosen key is not in the environment, it will be included.
3778
*
3879
* After the execution of [block], the environment is set to what it was before.
3980
*
4081
* **ATTENTION**: This code is susceptible to race conditions. If you attempt to change the environment while it was
4182
* already changed, the result is inconsistent, as the System Environment Map is a single map.
4283
*/
43-
inline fun <T> withEnvironment(environment: Map<String, String?>, block: () -> T): T {
84+
inline fun <T> withEnvironment(environment: Map<String, String?>, mode: OverrideMode = SetOrError, block: () -> T): T {
4485
val isWindows = "windows" in System.getProperty("os.name").orEmpty().lowercase()
4586
val originalEnvironment = if (isWindows) {
4687
System.getenv().toSortedMap(String.CASE_INSENSITIVE_ORDER)
4788
} else {
4889
System.getenv().toMap()
4990
}
5091

51-
setEnvironmentMap(setOrOverride(originalEnvironment, environment))
92+
setEnvironmentMap(mode.override(originalEnvironment, environment))
5293

5394
try {
5495
return block()
@@ -103,6 +144,3 @@ private fun MutableMap<String, String>.putReplacingNulls(map: Map<String, String
103144
if (value == null) remove(key) else put(key, value)
104145
}
105146
}
106-
107-
fun setOrOverride(originalValues: Map<String, String>, newValues: Map<String, String?>) =
108-
originalValues.toMutableMap().apply { putReplacingNulls(newValues) }

0 commit comments

Comments
 (0)