From 6e3cc41334688be0ab9225ab5fdc7a2e92fe3d4d Mon Sep 17 00:00:00 2001 From: Joacim Zschimmer Date: Wed, 11 Dec 2024 09:56:37 +0100 Subject: [PATCH] Parse system property switches correctly --- .../AgentConfigurationTest.scala | 3 ++- .../js7/base/catsutils/OurIORuntime.scala | 3 ++- .../js7/base/log/Log4jThreadContextMap.scala | 5 ++--- .../js7/base/thread/VirtualThreads.scala | 3 ++- .../js7/base/test/TestResultCollector.scala | 3 ++- .../js7/base/log/LoggingEscapeCodes.scala | 4 +++- .../utils/SystemPropertiesExtensions.scala | 13 +++++++++++ .../src/main/scala/js7/base/utils/Tests.scala | 8 ++++--- .../SystemPropertiesExtensionsTest.scala | 22 +++++++++++++++++++ .../configuration/Js7Configuration.scala | 7 ++---- .../ControllerConfigurationTest.scala | 3 ++- .../js7/data/session/HttpSessionApi.scala | 4 ++-- 12 files changed, 59 insertions(+), 19 deletions(-) create mode 100644 js7-base/shared/src/main/scala/js7/base/utils/SystemPropertiesExtensions.scala create mode 100644 js7-base/shared/src/test/scala/js7/base/utils/SystemPropertiesExtensionsTest.scala diff --git a/js7-agent/src/test/scala/js7/agent/configuration/AgentConfigurationTest.scala b/js7-agent/src/test/scala/js7/agent/configuration/AgentConfigurationTest.scala index 5d5cb8400d..a0008f52df 100644 --- a/js7-agent/src/test/scala/js7/agent/configuration/AgentConfigurationTest.scala +++ b/js7-agent/src/test/scala/js7/agent/configuration/AgentConfigurationTest.scala @@ -11,6 +11,7 @@ import js7.base.io.file.FileUtils.* import js7.base.io.file.FileUtils.syntax.* import js7.base.test.OurTestSuite import js7.base.utils.ScalaUtils.syntax.* +import js7.base.utils.SystemPropertiesExtensions.asSwitch import js7.cluster.ClusterConf import js7.common.commandline.CommandLineArguments import js7.common.pekkohttp.web.data.WebServerPort @@ -46,7 +47,7 @@ final class AgentConfigurationTest extends OurTestSuite: .orThrow clusterConf.copy( journalConf = clusterConf.journalConf.copy( - slowCheckState = sys.props.get("js7.test").fold(false)(StringAsBoolean(_)))) + slowCheckState = sys.props.asSwitch("js7.test"))) }, name = AgentConfiguration.DefaultName) }) diff --git a/js7-base/jvm/src/main/scala/js7/base/catsutils/OurIORuntime.scala b/js7-base/jvm/src/main/scala/js7/base/catsutils/OurIORuntime.scala index 21101502c8..a068301d07 100644 --- a/js7-base/jvm/src/main/scala/js7/base/catsutils/OurIORuntime.scala +++ b/js7-base/jvm/src/main/scala/js7/base/catsutils/OurIORuntime.scala @@ -17,6 +17,7 @@ import js7.base.utils.ByteUnits.toKiBGiB import js7.base.utils.Missing.getOrElse import js7.base.utils.ScalaUtils.* import js7.base.utils.ScalaUtils.syntax.* +import js7.base.utils.SystemPropertiesExtensions.asSwitch import js7.base.utils.Tests.isTestParallel import js7.base.utils.{Missing, Tests} import scala.concurrent.ExecutionContext @@ -28,7 +29,7 @@ object OurIORuntime: private lazy val logger = Logger[this.type] val useCommonIORuntime: Boolean = - sys.props.contains("js7.test.commonIORuntime") || sys.props.contains("test.speed") + sys.props.asSwitch("js7.test.commonIORuntime") || sys.props.contains("test.speed") val commonThreadPrefix = "js7" diff --git a/js7-base/jvm/src/main/scala/js7/base/log/Log4jThreadContextMap.scala b/js7-base/jvm/src/main/scala/js7/base/log/Log4jThreadContextMap.scala index 1cbe7f0e67..e807b851d1 100644 --- a/js7-base/jvm/src/main/scala/js7/base/log/Log4jThreadContextMap.scala +++ b/js7-base/jvm/src/main/scala/js7/base/log/Log4jThreadContextMap.scala @@ -5,6 +5,7 @@ import js7.base.BuildInfo import js7.base.log.Log4jThreadContextMap.* import js7.base.system.startup.StartUp import js7.base.utils.Lazy +import js7.base.utils.SystemPropertiesExtensions.asSwitch import js7.base.utils.Tests.isTest import org.apache.logging.log4j.spi.{CopyOnWrite, ReadOnlyThreadContextMap, ThreadContextMap} import org.apache.logging.log4j.util.StringMap @@ -96,9 +97,7 @@ object Log4jThreadContextMap: case lzy: Lazy[String] => lzy.value private val isDebug: Boolean = - sys.props.get("log4j2.debug") match - case Some("" | "true") => true - case _ => false + sys.props.asSwitch("log4j2.debug") def initialize(name: String): Unit = keyToValue.put("js7.serverId", name) // May be overwritten later by a more specific value diff --git a/js7-base/jvm/src/main/scala/js7/base/thread/VirtualThreads.scala b/js7-base/jvm/src/main/scala/js7/base/thread/VirtualThreads.scala index 0e72a3d429..cb544ce414 100644 --- a/js7-base/jvm/src/main/scala/js7/base/thread/VirtualThreads.scala +++ b/js7-base/jvm/src/main/scala/js7/base/thread/VirtualThreads.scala @@ -3,12 +3,13 @@ package js7.base.thread import java.util.concurrent.{ExecutorService, Executors, ThreadFactory} import js7.base.log.Logger import js7.base.utils.ScalaUtils.syntax.* +import js7.base.utils.SystemPropertiesExtensions.asSwitch object VirtualThreads: private val logger = Logger[this.type] private var hasVirtualThreads = - Runtime.version.feature >= 19 && sys.props.contains("js7.virtualThreads") + Runtime.version.feature >= 19 && sys.props.asSwitch("js7.virtualThreads") private lazy val maybeNewVirtualThreadPerTaskExecutor: Option[() => ExecutorService] = for diff --git a/js7-base/jvm/src/test/scala/js7/base/test/TestResultCollector.scala b/js7-base/jvm/src/test/scala/js7/base/test/TestResultCollector.scala index bec168396d..2bdd1fc7da 100644 --- a/js7-base/jvm/src/test/scala/js7/base/test/TestResultCollector.scala +++ b/js7-base/jvm/src/test/scala/js7/base/test/TestResultCollector.scala @@ -9,6 +9,7 @@ import js7.base.system.JavaHeapDump.dumpHeapTo import js7.base.test.LoggingTestAdder.Result import js7.base.thread.VirtualThreads.newMaybeVirtualThread import js7.base.utils.ScalaUtils.syntax.{RichBoolean, RichThrowable} +import js7.base.utils.SystemPropertiesExtensions.asSwitch import org.scalatest.exceptions.TestPendingException import scala.collection.mutable import scala.jdk.CollectionConverters.MapHasAsScala @@ -32,7 +33,7 @@ private object TestResultCollector: newMaybeVirtualThread("TestResultCollector-shutdown-hook") { logThreads() logger.info(s"Test summary:\n$asString\n") - if sys.props.contains("js7.dumpHeap") then dumpJavaHeap() + if sys.props.asSwitch("js7.dumpHeap") then dumpJavaHeap() if false then Log4j.shutdown() // Set shutdownHook="disable" in project/log4j2.xml !!! }) diff --git a/js7-base/shared/src/main/scala/js7/base/log/LoggingEscapeCodes.scala b/js7-base/shared/src/main/scala/js7/base/log/LoggingEscapeCodes.scala index b5e2d75b56..fdb2d823ce 100644 --- a/js7-base/shared/src/main/scala/js7/base/log/LoggingEscapeCodes.scala +++ b/js7-base/shared/src/main/scala/js7/base/log/LoggingEscapeCodes.scala @@ -1,9 +1,11 @@ package js7.base.log +import js7.base.utils.SystemPropertiesExtensions.asSwitch + object LoggingEscapeCodes: val isColorAllowed: Boolean = - sys.props.get("js7.log.colored").forall(Set("true", "yes", "on", "")) + sys.props.asSwitch("js7.log.colored") /** Reset color and mode. */ val resetColor: String = if !isColorAllowed then "" else AnsiEscapeCodes.resetColor diff --git a/js7-base/shared/src/main/scala/js7/base/utils/SystemPropertiesExtensions.scala b/js7-base/shared/src/main/scala/js7/base/utils/SystemPropertiesExtensions.scala new file mode 100644 index 0000000000..a111a8f50a --- /dev/null +++ b/js7-base/shared/src/main/scala/js7/base/utils/SystemPropertiesExtensions.scala @@ -0,0 +1,13 @@ +package js7.base.utils + +import js7.base.convert.As.StringAsBoolean +import scala.sys.SystemProperties + +object SystemPropertiesExtensions: + + extension (properties: SystemProperties) + def asSwitch(key: String): Boolean = + properties.get(key) match + case None => false + case Some("") => true + case Some(string) => StringAsBoolean(string) diff --git a/js7-base/shared/src/main/scala/js7/base/utils/Tests.scala b/js7-base/shared/src/main/scala/js7/base/utils/Tests.scala index ee431096b6..0a05bc419c 100644 --- a/js7-base/shared/src/main/scala/js7/base/utils/Tests.scala +++ b/js7-base/shared/src/main/scala/js7/base/utils/Tests.scala @@ -1,9 +1,10 @@ package js7.base.utils -import js7.base.convert.As.StringAsBoolean import js7.base.log.Logger +import js7.base.utils.SystemPropertiesExtensions.asSwitch object Tests: + val (isIntelliJIdea, isScalaTest, isSbt, isTest, isStrict) = val classNames = TestsPlatform.allActiveClasses @@ -15,8 +16,9 @@ object Tests: val isScalaTest = hasPackagePrefix(Set("org.scalatest.")) val isSbt = hasPackagePrefix(Set("xsbt.boot.")) val isTest = (isScalaTest || isSbt) - && !sys.props.get("js7.noTest").fold(false)(StringAsBoolean(_)) - val isStrict = isTest || sys.props.get("js7.strict").fold(false)(StringAsBoolean(_)) + && !sys.props.asSwitch("js7.noTest") + && !sys.props.contains("test.speed") + val isStrict = isTest || sys.props.asSwitch("js7.strict") (isIntelliJIdea, isScalaTest, isSbt, isTest, isStrict) diff --git a/js7-base/shared/src/test/scala/js7/base/utils/SystemPropertiesExtensionsTest.scala b/js7-base/shared/src/test/scala/js7/base/utils/SystemPropertiesExtensionsTest.scala new file mode 100644 index 0000000000..a290c5b45b --- /dev/null +++ b/js7-base/shared/src/test/scala/js7/base/utils/SystemPropertiesExtensionsTest.scala @@ -0,0 +1,22 @@ +package js7.base.utils + +import js7.base.test.OurTestSuite +import js7.base.utils.SystemPropertiesExtensions.asSwitch + +final class SystemPropertiesExtensionsTest extends OurTestSuite: + + "asSwitch" in: + assert(sys.props.asSwitch("js7.SystemPropertiesExtensionsTest.undefined") == false) + + Seq( + "" -> true, + "false" -> false, + "off" -> false, + "no" -> false, + "true" -> true, + "on" -> true, + "yes" -> true + ).foreach: (string, bool) => + val key = "js7.SystemPropertiesExtensionsTest" + sys.props.put(key, string) + assert(sys.props.asSwitch(key) == bool) diff --git a/js7-common/src/main/scala/js7/common/configuration/Js7Configuration.scala b/js7-common/src/main/scala/js7/common/configuration/Js7Configuration.scala index 68395d939c..55dbf9fd7c 100644 --- a/js7-common/src/main/scala/js7/common/configuration/Js7Configuration.scala +++ b/js7-common/src/main/scala/js7/common/configuration/Js7Configuration.scala @@ -4,6 +4,7 @@ import com.typesafe.config.{Config, ConfigFactory} import js7.base.BuildInfo import js7.base.configutils.Configs import js7.base.io.JavaResource +import js7.base.utils.Tests.isTest import scala.jdk.CollectionConverters.* object Js7Configuration: @@ -12,11 +13,7 @@ object Js7Configuration: "js7.version" -> BuildInfo.version, "js7.longVersion" -> BuildInfo.longVersion, "js7.prettyVersion" -> BuildInfo.prettyVersion, - "js7.test" -> ( - if sys.props.contains("test.speed") then - "off" - else - sys.props.getOrElse("js7.test", "off"))) + "js7.test" -> isTest.toString) ConfigFactory .parseMap(map.asJava) .withFallback( diff --git a/js7-controller/src/test/scala/js7/controller/configuration/ControllerConfigurationTest.scala b/js7-controller/src/test/scala/js7/controller/configuration/ControllerConfigurationTest.scala index c74d60f781..37e4360b93 100644 --- a/js7-controller/src/test/scala/js7/controller/configuration/ControllerConfigurationTest.scala +++ b/js7-controller/src/test/scala/js7/controller/configuration/ControllerConfigurationTest.scala @@ -10,6 +10,7 @@ import js7.base.io.file.FileUtils.syntax.* import js7.base.test.OurTestSuite import js7.base.time.ScalaTime.* import js7.base.utils.DelayConf +import js7.base.utils.SystemPropertiesExtensions.asSwitch import js7.cluster.ClusterConf import js7.common.commandline.CommandLineArguments import js7.common.http.configuration.RecouplingStreamReaderConf @@ -50,7 +51,7 @@ final class ControllerConfigurationTest extends OurTestSuite, BeforeAndAfterAll: pekkoAskTimeout = 1.h, clusterConf = ClusterConf( JournalConf.fromConfig(configuration.config) - .copy(slowCheckState = sys.props.get("js7.test").fold(false)(StringAsBoolean(_))), + .copy(slowCheckState = sys.props.asSwitch("js7.test")), NodeId("Primary"), isBackup = false, None, RecouplingStreamReaderConf( timeout = Some(6500.ms), // Between 3s and 10s diff --git a/js7-data/shared/src/main/scala/js7/data/session/HttpSessionApi.scala b/js7-data/shared/src/main/scala/js7/data/session/HttpSessionApi.scala index e649ad7663..62ad28dc3c 100644 --- a/js7-data/shared/src/main/scala/js7/data/session/HttpSessionApi.scala +++ b/js7-data/shared/src/main/scala/js7/data/session/HttpSessionApi.scala @@ -17,6 +17,7 @@ import js7.base.utils.{AsyncLock, Atomic} import js7.base.utils.Atomic.extensions.* import js7.base.utils.CatsUtils.syntax.* import js7.base.utils.ScalaUtils.syntax.RichAny +import js7.base.utils.SystemPropertiesExtensions.asSwitch import js7.base.utils.Tests.isTest import js7.base.version.Js7Versions.checkNonMatchingVersion import js7.base.version.Version @@ -125,8 +126,7 @@ trait HttpSessionApi extends SessionApi, HasSessionToken: object HttpSessionApi: private val logger = Logger[this.type] - private val isPasswordLoggable = isTest && - sys.props.get("js7.test.log-password").fold(false)(StringAsBoolean.apply) + private val isPasswordLoggable = isTest && sys.props.asSwitch("js7.test.log-password") private[session] def logNonMatchingVersion( otherVersion: Version,