Skip to content

Commit

Permalink
add more tests, and test in CI
Browse files Browse the repository at this point in the history
  • Loading branch information
alyssaruth committed Nov 22, 2023
1 parent 558981c commit de8a897
Show file tree
Hide file tree
Showing 10 changed files with 488 additions and 94 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,7 @@ jobs:
java-version: 11.0.18
- name: Ktlint format
run: ./gradlew :${{ matrix.project }}:ktlintFormat
- name: Build
run: xvfb-run --auto-servernum ./gradlew :${{ matrix.project }}:build
- name: Compile
run: ./gradlew :${{ matrix.project }}:compileKotlin
- name: Test
run: xvfb-run --auto-servernum ./gradlew :${{ matrix.project }}:test
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package logging

import logging.exceptions.ApplicationFault
import utils.InjectedThings.logger
import java.lang.Thread.UncaughtExceptionHandler

Expand All @@ -9,8 +8,6 @@ class LoggerUncaughtExceptionHandler : UncaughtExceptionHandler {
if (isSuppressed(arg1)) {
// Still stack trace, but don't show an error message or email a log
logger.warn(CODE_UNCAUGHT_EXCEPTION, "Suppressing uncaught exception: $arg1", KEY_THREAD to arg0.toString(), KEY_EXCEPTION_MESSAGE to arg1.message)
} else if (arg1 is ApplicationFault) {
logger.error(arg1.loggingCode, "Uncaught exception: ${arg1.message}", arg1, KEY_THREAD to arg0.toString())
} else {
logger.error(CODE_UNCAUGHT_EXCEPTION, "Uncaught exception: $arg1 in thread $arg0", arg1, KEY_THREAD to arg0.toString())
}
Expand Down
81 changes: 0 additions & 81 deletions core/src/main/kotlin/logging/LoggingCodes.kt
Original file line number Diff line number Diff line change
@@ -1,89 +1,8 @@
package logging

// Info
val CODE_SQL = LoggingCode("sql")
val CODE_BULK_SQL = LoggingCode("bulkSql")
val CODE_JUST_UPDATED = LoggingCode("justUpdated")
val CODE_MEMORY_SETTINGS = LoggingCode("memorySettings")
val CODE_TABLE_CREATED = LoggingCode("tableCreated")
val CODE_TABLE_EXISTS = LoggingCode("tableExists")
val CODE_LOOK_AND_FEEL_SET = LoggingCode("lafSet")
val CODE_DATABASE_UP_TO_DATE = LoggingCode("databaseCurrent")
val CODE_DATABASE_NEEDS_UPDATE = LoggingCode("databaseNeedsUpdate")
val CODE_DATABASE_CREATING = LoggingCode("databaseCreating")
val CODE_DATABASE_CREATED = LoggingCode("databaseCreated")
val CODE_THREAD_STACKS = LoggingCode("threadStacks")
val CODE_THREAD_STACK = LoggingCode("threadStack")
val CODE_NEW_CONNECTION = LoggingCode("newConnection")
val CODE_SANITY_CHECK_STARTED = LoggingCode("sanityCheckStarted")
val CODE_SANITY_CHECK_COMPLETED = LoggingCode("sanityCheckCompleted")
val CODE_SANITY_CHECK_RESULT = LoggingCode("sanityCheckResult")
val CODE_SIMULATION_STARTED = LoggingCode("simulationStarted")
val CODE_SIMULATION_PROGRESS = LoggingCode("simulationProgress")
val CODE_SIMULATION_CANCELLED = LoggingCode("simulationCancelled")
val CODE_SIMULATION_FINISHED = LoggingCode("simulationFinished")
val CODE_DIALOG_SHOWN = LoggingCode("dialogShown")
val CODE_DIALOG_CLOSED = LoggingCode("dialogClosed")
val CODE_COMMAND_ENTERED = LoggingCode("commandEntered")
val CODE_UPDATE_CHECK = LoggingCode("updateCheck")
val CODE_UPDATE_CHECK_RESULT = LoggingCode("updateCheckResult")
val CODE_LOADED_RESOURCES = LoggingCode("loadedResources")
val CODE_STARTING_BACKUP = LoggingCode("startingBackup")
val CODE_STARTING_RESTORE = LoggingCode("startingRestore")
val CODE_SLOW_DARTBOARD_RENDER = LoggingCode("slowDartboardRender")
val CODE_PLAYER_PAUSED = LoggingCode("playerPaused")
val CODE_PLAYER_UNPAUSED = LoggingCode("playerUnpaused")
val CODE_FETCHING_DATABASE = LoggingCode("fetchingDatabase")
val CODE_FETCHED_DATABASE = LoggingCode("fetchedDatabase")
val CODE_UNZIPPED_DATABASE = LoggingCode("unzippedDatabase")
val CODE_PUSHING_DATABASE = LoggingCode("pushingDatabase")
val CODE_ZIPPED_DATABASE = LoggingCode("zippedDatabase")
val CODE_PUSHED_DATABASE = LoggingCode("pushedDatabase")
val CODE_PUSHED_DATABASE_BACKUP = LoggingCode("pushedDatabaseBackup")
val CODE_MERGE_STARTED = LoggingCode("mergeStarted")
val CODE_MERGING_ENTITY = LoggingCode("mergingEntity")
val CODE_ACHIEVEMENT_CONVERSION_STARTED = LoggingCode("achievementConversionStarted")
val CODE_ACHIEVEMENT_CONVERSION_FINISHED = LoggingCode("achievementConversionFinished")
val CODE_SWITCHING_FILES = LoggingCode("switchingFiles")
val CODE_REVERT_TO_PULL = LoggingCode("revertToPull")
val CODE_SWITCHED_SCREEN = LoggingCode("switchedScreen")
val CODE_GAME_LAUNCHED = LoggingCode("gameLaunched")
val CODE_MATCH_LAUNCHED = LoggingCode("matchLaunched")
val CODE_MATCH_FINISHED = LoggingCode("matchFinished")

// Warn
val CODE_UNEXPECTED_ARGUMENT = LoggingCode("unexpectedArgument")
val CODE_DATABASE_TOO_OLD = LoggingCode("databaseTooOld")
val CODE_RESOURCE_CACHE_NOT_INITIALISED = LoggingCode("resourceCacheNotInitialised")
val CODE_DATABASE_IN_USE = LoggingCode("databaseInUse")
val CODE_NO_STREAMS = LoggingCode("noStreams")

// Error
val CODE_LOOK_AND_FEEL_ERROR = LoggingCode("lafError")
val CODE_SQL_EXCEPTION = LoggingCode("sqlException")
val CODE_UNCAUGHT_EXCEPTION = LoggingCode("uncaughtException")
val CODE_SIMULATION_ERROR = LoggingCode("simulationError")
val CODE_LOAD_ERROR = LoggingCode("loadError")
val CODE_INSTANTIATION_ERROR = LoggingCode("instantiationError")
val CODE_AUDIO_ERROR = LoggingCode("audioError")
val CODE_SCREEN_LOAD_ERROR = LoggingCode("screenLoadError")
val CODE_UPDATE_ERROR = LoggingCode("updateError")
val CODE_PARSE_ERROR = LoggingCode("parseError")
val CODE_BATCH_ERROR = LoggingCode("batchFileError")
val CODE_TEST_CONNECTION_ERROR = LoggingCode("testConnectionError")
val CODE_RESOURCE_LOAD_ERROR = LoggingCode("resourceLoadError")
val CODE_COMMAND_ERROR = LoggingCode("commandError")
val CODE_RENDER_ERROR = LoggingCode("renderError")
val CODE_FILE_ERROR = LoggingCode("fileError")
val CODE_SWING_ERROR = LoggingCode("swingError")
val CODE_AI_ERROR = LoggingCode("aiError")
val CODE_ELASTICSEARCH_ERROR = LoggingCode("elasticsearchError")
val CODE_MERGE_ERROR = LoggingCode("mergeError")
val CODE_SYNC_ERROR = LoggingCode("syncError")
val CODE_PUSH_ERROR = LoggingCode("pushError")
val CODE_PULL_ERROR = LoggingCode("pullError")
val CODE_BACKUP_ERROR = LoggingCode("backupError")
val CODE_RESTORE_ERROR = LoggingCode("restoreError")
val CODE_DELETE_ERROR = LoggingCode("deleteError")
val CODE_HYPERLINK_ERROR = LoggingCode("hyperlinkError")
val CODE_EDT_FROZEN = LoggingCode("edtFrozen")
8 changes: 0 additions & 8 deletions core/src/main/kotlin/logging/exceptions/ApplicationFault.kt

This file was deleted.

7 changes: 7 additions & 0 deletions core/src/test/kotlin/helper/TestConstants.kt
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
import java.time.Instant
import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.util.*

val CURRENT_TIME: Instant = Instant.parse("2020-04-13T11:04:00.00Z")
val CURRENT_TIME_STRING: String = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
.withLocale(Locale.UK)
.withZone(ZoneId.systemDefault())
.format(CURRENT_TIME)
50 changes: 50 additions & 0 deletions core/src/test/kotlin/helper/TestUtils.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package helper

import CURRENT_TIME
import io.kotest.matchers.maps.shouldContainExactly
import logging.LogRecord
import logging.LoggingCode
import logging.Severity
import java.awt.Component
import java.awt.Container
import java.time.Instant

fun LogRecord.shouldContainKeyValues(vararg values: Pair<String, Any?>) {
keyValuePairs.shouldContainExactly(mapOf(*values))
}

fun makeLogRecord(
timestamp: Instant = CURRENT_TIME,
severity: Severity = Severity.INFO,
loggingCode: LoggingCode = LoggingCode("log"),
message: String = "A thing happened",
errorObject: Throwable? = null,
keyValuePairs: Map<String, Any?> = mapOf(),
) =
LogRecord(timestamp, severity, loggingCode, message, errorObject, keyValuePairs)

/**
* Recurses through all child components, returning an ArrayList of all children of the appropriate type
*/
inline fun <reified T> Container.getAllChildComponentsForType(): List<T> {
val ret = mutableListOf<T>()

val components = components
addComponents(ret, components, T::class.java)

return ret
}

@Suppress("UNCHECKED_CAST")
fun <T> addComponents(ret: MutableList<T>, components: Array<Component>, desiredClazz: Class<T>) {
for (comp in components) {
if (desiredClazz.isInstance(comp)) {
ret.add(comp as T)
}

if (comp is Container) {
val subComponents = comp.components
addComponents(ret, subComponents, desiredClazz)
}
}
}
68 changes: 68 additions & 0 deletions core/src/test/kotlin/logging/LogDestinationSystemOutTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package logging

import CURRENT_TIME_STRING
import helper.AbstractTest
import helper.makeLogRecord
import io.kotest.matchers.string.shouldContain
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import java.io.ByteArrayOutputStream
import java.io.PrintStream

class LogDestinationSystemOutTest : AbstractTest() {
private val originalOut = System.out

private val newOut = ByteArrayOutputStream()

@BeforeEach
fun beforeEach() {
System.setOut(PrintStream(newOut))
}

@AfterEach
fun afterEach() {
System.setOut(originalOut)
}

@Test
fun `Should log the record to system out`() {
val dest = LogDestinationSystemOut()

val record = makeLogRecord(severity = Severity.INFO, loggingCode = LoggingCode("some.event"), message = "blah")
dest.log(record)

val output = newOut.toString()
output shouldContain "$CURRENT_TIME_STRING [some.event] blah"
}

@Test
fun `Should print the stack trace for errors`() {
val dest = LogDestinationSystemOut()

val error = Throwable("oh no")
val record = makeLogRecord(severity = Severity.ERROR, loggingCode = LoggingCode("some.event"), message = "blah", errorObject = error)
dest.log(record)

val output = newOut.toString()
output shouldContain "$CURRENT_TIME_STRING [some.event] blah"
output shouldContain "$CURRENT_TIME_STRING java.lang.Throwable: oh no"
}

@Test
fun `Should print the stack for a thread dump`() {
val dest = LogDestinationSystemOut()

val record = makeLogRecord(
severity = Severity.INFO,
loggingCode = LoggingCode("some.event"),
message = "blah",
keyValuePairs = mapOf(KEY_STACK to "at Something.blah"),
)
dest.log(record)

val output = newOut.toString()
output shouldContain "$CURRENT_TIME_STRING [some.event] blah"
output shouldContain "at Something.blah"
}
}
Loading

0 comments on commit de8a897

Please sign in to comment.