Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added ConfigFailFast check for invalid dateTime configuration #411

Merged
merged 12 commits into from
Jan 24, 2023
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Adaption of abbreviations in PVModel and adjacent classes to naming convention [#326](https://github.com/ie3-institute/simona/issues/326)
- Fixed Latex equations [#264](https://github.com/ie3-institute/simona/issues/264)
- Documentation of the simulation configuration [#334](https://github.com/ie3-institute/simona/issues/334)
- Adapted to changes of Quantity units in PSU and PSDM [#419](https://github.com/ie3-institute/simona/pull/419)
- Adapted entry in Done message and deleted parallel window [#159](https://github.com/ie3-institute/simona/issues/159)
- Added ConfigFailFast check for invalid dateTime configuration [#344](https://github.com/ie3-institute/simona/issues/344)

### Fixed
- Location of `vn_simona` test grid (was partially in Berlin and Dortmund) [#72](https://github.com/ie3-institute/simona/issues/72)
Expand Down
44 changes: 30 additions & 14 deletions src/main/scala/edu/ie3/simona/config/ConfigFailFast.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import edu.ie3.util.{StringUtils, TimeUtil}
import tech.units.indriya.quantity.Quantities
import tech.units.indriya.unit.Units

import java.time.ZonedDateTime
import java.time.format.DateTimeParseException
import java.time.temporal.ChronoUnit
import java.util.UUID
import scala.util.{Failure, Success, Try}
Expand Down Expand Up @@ -106,7 +108,7 @@ case object ConfigFailFast extends LazyLogging {
def check(simonaConfig: SimonaConfig): Unit = {

/* check date and time */
checkDateTime(simonaConfig.simona.time)
checkTimeConfig(simonaConfig.simona.time)

// check if the provided combinations of refSystems provided are valid
val refSystems = simonaConfig.simona.gridConfig.refSystems
Expand Down Expand Up @@ -203,24 +205,38 @@ case object ConfigFailFast extends LazyLogging {
* @param timeConfig
* the time config
*/
private def checkDateTime(
private def checkTimeConfig(
timeConfig: SimonaConfig.Simona.Time
): Unit = {

// check if the provided date/time values match the SimonaConstants definition for date/time
val timeAndDates = Map(
"simonaConfig.simona.time.startDateTime" -> timeConfig.startDateTime,
"simonaConfig.simona.time.endDateTime" -> timeConfig.endDateTime
)
timeAndDates.foreach { case (configParameter, dateTimeString) =>
Try {
TimeUtil.withDefaults.toZonedDateTime(dateTimeString)
}.getOrElse(
val startDate = createDateTime(timeConfig.startDateTime)
val endDate = createDateTime(timeConfig.endDateTime)

if (startDate.isAfter(endDate))
throw new InvalidConfigParameterException(
s"Invalid time configuration." +
s"Please ensure that the start time of the simulation is before the end time."
)
}

/** Creates a ZonedDateTime from String. If a faulty dateTime string is
* passed, an [[InvalidConfigParameterException]] is thrown
*
* @param dateTimeString
* the dateTimeString that should be checked
*/
private def createDateTime(
dateTimeString: String
): ZonedDateTime = {
try {
TimeUtil.withDefaults.toZonedDateTime(dateTimeString)
} catch {
case e: DateTimeParseException =>
throw new InvalidConfigParameterException(
s"Invalid dateTimeString for config parameter $configParameter: $dateTimeString. " +
s"Please ensure that your date/time parameter match the following pattern: ‘yyyy-MM-dd HH:mm:ss'"
s"Invalid dateTimeString: $dateTimeString." +
s"Please ensure that your date/time parameter match the following pattern: 'yyyy-MM-dd HH:mm:ss'",
e
)
)
}
}

Expand Down
41 changes: 33 additions & 8 deletions src/test/scala/edu/ie3/simona/config/ConfigFailFastSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,20 @@ import edu.ie3.simona.config.SimonaConfig.{BaseCsvParams, ResultKafkaParams}
import edu.ie3.simona.exceptions.InvalidConfigParameterException
import edu.ie3.simona.test.common.{ConfigTestData, UnitSpec}
import edu.ie3.simona.util.ConfigUtil.{CsvConfigUtil, NotifierIdentifier}
import edu.ie3.util.TimeUtil

import java.time.Duration
import java.time.{Duration, ZonedDateTime}
import java.time.temporal.ChronoUnit

class ConfigFailFastSpec extends UnitSpec with ConfigTestData {
"Validating the configs" when {
"validating the simona config" when {
"Checking date input" should {
val checkDateTime = PrivateMethod[Unit](Symbol("checkDateTime"))
val checkTimeConfig = PrivateMethod[Unit](Symbol("checkTimeConfig"))

"let valid input pass" in {
noException shouldBe thrownBy {
ConfigFailFast invokePrivate checkDateTime(
ConfigFailFast invokePrivate checkTimeConfig(
new Time(
"2020-06-18 13:41:00",
None,
Expand All @@ -39,18 +40,42 @@ class ConfigFailFastSpec extends UnitSpec with ConfigTestData {
}
}

"identify invalid input" in {
"identify invalid date or time configuration" in {
intercept[InvalidConfigParameterException] {
ConfigFailFast invokePrivate checkDateTime(
ConfigFailFast invokePrivate checkTimeConfig(
new Time(
"2020-06-18 13:41:00",
None,
"total non-sense",
"2020-07-18 13:41:00",
true
)
)
}.getMessage shouldBe "Invalid dateTimeString for config parameter simonaConfig.simona.time.startDateTime: total non-sense. Please " +
"ensure that your date/time parameter match the following pattern: ‘yyyy-MM-dd HH:mm:ss'"
}.getMessage shouldBe "Invalid time configuration." +
"Please ensure that the start time of the simulation is before the end time."
}
}

"Checking date string" should {
val createDateTime =
PrivateMethod[ZonedDateTime](Symbol("createDateTime"))

val dateTimeString: String = "2020-05-18 13:41:00"

"let valid input pass" in {

ConfigFailFast invokePrivate createDateTime(
dateTimeString
) shouldBe TimeUtil.withDefaults.toZonedDateTime(dateTimeString)

}

"identify invalid input" in {
intercept[InvalidConfigParameterException] {
ConfigFailFast invokePrivate createDateTime(
"total non-sense"
)
}.getMessage shouldBe "Invalid dateTimeString: total non-sense." +
"Please ensure that your date/time parameter match the following pattern: 'yyyy-MM-dd HH:mm:ss'"
}
}

Expand Down