Skip to content

Commit

Permalink
Merge pull request #38 from craigatk/failure
Browse files Browse the repository at this point in the history
(fix) Better handle parsing errors when saving results and standardize on JUnit5 style test annotations
  • Loading branch information
craigatk committed Apr 2, 2020
2 parents f3fdbc2 + 8f78c10 commit dfa5e3f
Show file tree
Hide file tree
Showing 39 changed files with 185 additions and 96 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ package projektor.incomingresults

import kotlinx.coroutines.*
import org.slf4j.LoggerFactory
import projektor.incomingresults.model.GroupedResults
import projektor.server.api.PublicId
import projektor.server.api.TestRunSummary
import projektor.server.api.results.ResultsProcessingStatus
import projektor.testrun.TestRunRepository

Expand All @@ -28,36 +26,22 @@ class GroupedTestResultsService(
return publicId
}

suspend fun doPersistTestResults(publicId: PublicId, groupedResultsXml: String): TestRunSummary {
testResultsProcessingService.updateResultsProcessingStatus(publicId, ResultsProcessingStatus.PROCESSING)

val groupedResults = parseGroupedResults(publicId, groupedResultsXml)
val testRunSummary = persistGroupedResults(publicId, groupedResults)

testResultsProcessingService.updateResultsProcessingStatus(publicId, ResultsProcessingStatus.SUCCESS)
suspend fun doPersistTestResults(publicId: PublicId, groupedResultsXml: String) {
try {
testResultsProcessingService.updateResultsProcessingStatus(publicId, ResultsProcessingStatus.PROCESSING)

return testRunSummary
}
val groupedResults = groupedResultsConverter.parseAndConvertGroupedResults(groupedResultsXml)
testRunRepository.saveGroupedTestRun(publicId, groupedResults)

private suspend fun parseGroupedResults(publicId: PublicId, groupedResultsXml: String): GroupedResults =
try {
groupedResultsConverter.parseAndConvertGroupedResults(groupedResultsXml)
testResultsProcessingService.updateResultsProcessingStatus(publicId, ResultsProcessingStatus.SUCCESS)
} catch (e: Exception) {
val errorMessage = "Error parsing test results: ${e.message}"
val errorMessage = "Error persisting test results: ${e.message}"
handleException(publicId, errorMessage, e)
}
}

private suspend fun persistGroupedResults(publicId: PublicId, groupedResults: GroupedResults): TestRunSummary =
try {
testRunRepository.saveGroupedTestRun(publicId, groupedResults)
} catch (e: Exception) {
val errorMessage = "Error saving test results: ${e.message}"
handleException(publicId, errorMessage, e)
}

private suspend fun handleException(publicId: PublicId, errorMessage: String, e: Exception): Nothing {
private suspend fun handleException(publicId: PublicId, errorMessage: String, e: Exception) {
logger.error(errorMessage, e)
testResultsProcessingService.recordResultsProcessingError(publicId, errorMessage)
throw PersistTestResultsException(publicId, errorMessage, e)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import org.slf4j.LoggerFactory
import projektor.parser.model.TestSuite
import projektor.results.processor.TestResultsProcessor
import projektor.server.api.PublicId
import projektor.server.api.TestRunSummary
import projektor.server.api.results.ResultsProcessingStatus
import projektor.testrun.TestRunRepository

Expand All @@ -29,37 +28,27 @@ class TestResultsService(
return publicId
}

suspend fun doPersistTestResults(publicId: PublicId, resultsBlob: String): TestRunSummary {
testResultsProcessingService.updateResultsProcessingStatus(publicId, ResultsProcessingStatus.PROCESSING)

val testSuites = parseTestSuites(publicId, resultsBlob)
val testRunSummary = persistTestSuites(publicId, testSuites)

testResultsProcessingService.updateResultsProcessingStatus(publicId, ResultsProcessingStatus.SUCCESS)

return testRunSummary
}

private suspend fun parseTestSuites(publicId: PublicId, resultsBlob: String): List<TestSuite> =
suspend fun doPersistTestResults(publicId: PublicId, resultsBlob: String) {
try {
val parsedTestSuites = testResultsProcessor.parseResultsBlob(resultsBlob)
parsedTestSuites.filter { !it.testCases.isNullOrEmpty() }
} catch (e: Exception) {
val errorMessage = "Error parsing test results: ${e.message}"
handleException(publicId, errorMessage, e)
}
testResultsProcessingService.updateResultsProcessingStatus(publicId, ResultsProcessingStatus.PROCESSING)

private suspend fun persistTestSuites(publicId: PublicId, testSuites: List<TestSuite>): TestRunSummary =
try {
val testSuites = parseTestSuites(resultsBlob)
testRunRepository.saveTestRun(publicId, testSuites)

testResultsProcessingService.updateResultsProcessingStatus(publicId, ResultsProcessingStatus.SUCCESS)
} catch (e: Exception) {
val errorMessage = "Error saving test results: ${e.message}"
val errorMessage = "Error persisting test results: ${e.message}"
handleException(publicId, errorMessage, e)
}
}

private fun parseTestSuites(resultsBlob: String): List<TestSuite> {
val parsedTestSuites = testResultsProcessor.parseResultsBlob(resultsBlob)
return parsedTestSuites.filter { !it.testCases.isNullOrEmpty() }
}

private suspend fun handleException(publicId: PublicId, errorMessage: String, e: Exception): Nothing {
private suspend fun handleException(publicId: PublicId, errorMessage: String, e: Exception) {
logger.error(errorMessage, e)
testResultsProcessingService.recordResultsProcessingError(publicId, errorMessage)
throw PersistTestResultsException(publicId, errorMessage, e)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ import io.ktor.application.Application
import io.ktor.config.MapApplicationConfig
import io.ktor.util.KtorExperimentalAPI
import java.math.BigDecimal
import kotlin.test.AfterTest
import org.awaitility.kotlin.await
import org.awaitility.kotlin.until
import org.jooq.DSLContext
import org.junit.jupiter.api.AfterEach
import org.koin.ktor.ext.get
import projektor.database.generated.tables.daos.*
import projektor.parser.ResultsXmlLoader
Expand All @@ -40,6 +40,7 @@ open class ApplicationTestCase {
lateinit var testFailureDao: TestFailureDao
lateinit var attachmentDao: TestRunAttachmentDao
lateinit var testRunSystemAttributesDao: TestRunSystemAttributesDao
lateinit var resultsProcessingDao: ResultsProcessingDao
lateinit var testRunDBGenerator: TestRunDBGenerator
lateinit var application: Application

Expand Down Expand Up @@ -99,6 +100,7 @@ open class ApplicationTestCase {
testFailureDao = TestFailureDao(dslContext.configuration())
attachmentDao = TestRunAttachmentDao(dslContext.configuration())
testRunSystemAttributesDao = TestRunSystemAttributesDao(dslContext.configuration())
resultsProcessingDao = ResultsProcessingDao(dslContext.configuration())
testRunDBGenerator = TestRunDBGenerator(testRunDao, testSuiteGroupDao, testSuiteDao, testCaseDao, testFailureDao)

this.application = application
Expand All @@ -108,7 +110,7 @@ open class ApplicationTestCase {
await until { attachmentDao.fetchByTestRunPublicId(publicId.id).size == attachmentCount }
}

@AfterTest
@AfterEach
fun closeDataSource() {
dataSource.close()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ package projektor
import com.zaxxer.hikari.HikariConfig
import com.zaxxer.hikari.HikariDataSource
import io.ktor.util.KtorExperimentalAPI
import kotlin.test.AfterTest
import kotlin.test.BeforeTest
import org.jooq.DSLContext
import org.jooq.SQLDialect
import org.jooq.impl.DSL
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeEach
import org.koin.core.context.startKoin
import org.koin.core.context.stopKoin
import org.koin.test.KoinTest
Expand All @@ -29,7 +29,7 @@ open class DatabaseRepositoryTestCase : KoinTest {
lateinit var testRunSystemAttributesDao: TestRunSystemAttributesDao

@KtorExperimentalAPI
@BeforeTest
@BeforeEach
fun setup() {
val hikariConfig = HikariConfig()

Expand Down Expand Up @@ -67,7 +67,7 @@ open class DatabaseRepositoryTestCase : KoinTest {
testRunDBGenerator = TestRunDBGenerator(testRunDao, testSuiteGroupDao, testSuiteDao, testCaseDao, testFailureDao)
}

@AfterTest
@AfterEach
fun closeDataSource() {
stopKoin()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import io.ktor.server.testing.setBody
import io.ktor.server.testing.withTestApplication
import io.ktor.util.KtorExperimentalAPI
import java.io.File
import kotlin.test.Test
import org.junit.jupiter.api.Test
import projektor.ApplicationTestCase
import projektor.TestSuiteData
import projektor.incomingresults.randomPublicId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import io.ktor.server.testing.withTestApplication
import io.ktor.util.KtorExperimentalAPI
import java.io.File
import java.math.BigDecimal
import kotlin.test.*
import org.junit.jupiter.api.Test
import projektor.ApplicationTestCase
import projektor.TestSuiteData
import projektor.incomingresults.randomPublicId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import io.ktor.server.testing.setBody
import io.ktor.server.testing.withTestApplication
import io.ktor.util.KtorExperimentalAPI
import java.io.File
import kotlin.test.*
import org.junit.jupiter.api.Test
import projektor.ApplicationTestCase
import projektor.TestSuiteData
import projektor.auth.AuthConfig
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package projektor.attachment

import kotlin.test.Test
import kotlinx.coroutines.runBlocking
import org.junit.jupiter.api.Test
import projektor.DatabaseRepositoryTestCase
import projektor.database.generated.tables.pojos.TestRunAttachment
import projektor.incomingresults.randomPublicId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import io.ktor.server.testing.setBody
import io.ktor.server.testing.withTestApplication
import io.ktor.util.KtorExperimentalAPI
import java.io.File
import kotlin.test.Test
import kotlin.test.assertNotNull
import org.junit.jupiter.api.Test
import projektor.ApplicationTestCase
import projektor.TestSuiteData
import projektor.incomingresults.randomPublicId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import io.ktor.http.HttpStatusCode
import io.ktor.server.testing.handleRequest
import io.ktor.server.testing.withTestApplication
import io.ktor.util.KtorExperimentalAPI
import kotlin.test.Test
import org.junit.jupiter.api.Test
import projektor.ApplicationTestCase
import projektor.server.api.config.ServerConfig
import strikt.api.expectThat
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ package projektor.incomingresults
import io.ktor.http.*
import io.ktor.server.testing.*
import io.ktor.util.KtorExperimentalAPI
import kotlin.test.*
import kotlin.test.assertNotNull
import kotlinx.coroutines.runBlocking
import org.awaitility.kotlin.await
import org.awaitility.kotlin.untilNotNull
import org.junit.jupiter.api.Test
import org.koin.ktor.ext.get
import projektor.ApplicationTestCase
import projektor.server.api.PublicId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import io.ktor.http.*
import io.ktor.server.testing.*
import io.ktor.util.KtorExperimentalAPI
import java.time.LocalDateTime
import kotlin.test.*
import kotlin.test.assertNotNull
import org.awaitility.kotlin.await
import org.awaitility.kotlin.untilNotNull
import org.junit.jupiter.api.Test
import projektor.ApplicationTestCase
import projektor.server.api.results.ResultsProcessing
import projektor.server.api.results.ResultsProcessingStatus
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package projektor.incomingresults

import kotlin.test.Test
import kotlin.test.assertNotNull
import kotlinx.coroutines.runBlocking
import org.awaitility.kotlin.await
import org.awaitility.kotlin.untilNotNull
import org.junit.jupiter.api.Test
import org.koin.core.inject
import projektor.DatabaseRepositoryTestCase
import projektor.parser.GroupedResultsXmlLoader
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import io.ktor.server.testing.handleRequest
import io.ktor.server.testing.setBody
import io.ktor.server.testing.withTestApplication
import io.ktor.util.KtorExperimentalAPI
import kotlin.test.Test
import kotlin.test.assertNotNull
import org.awaitility.kotlin.await
import org.awaitility.kotlin.untilNotNull
import org.junit.jupiter.api.Test
import projektor.ApplicationTestCase
import projektor.parser.GroupedResultsXmlLoader
import projektor.server.api.results.SaveResultsResponse
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package projektor.incomingresults

import io.ktor.http.HttpHeaders
import io.ktor.http.HttpMethod
import io.ktor.server.testing.handleRequest
import io.ktor.server.testing.setBody
import io.ktor.server.testing.withTestApplication
import io.ktor.util.KtorExperimentalAPI
import kotlin.test.assertNotNull
import org.awaitility.kotlin.await
import org.awaitility.kotlin.until
import org.junit.jupiter.api.Test
import projektor.ApplicationTestCase
import projektor.parser.GroupedResultsXmlLoader
import projektor.server.api.results.ResultsProcessingStatus
import projektor.server.api.results.SaveResultsResponse

@KtorExperimentalAPI
class SaveGroupedResultsErrorApplicationTest : ApplicationTestCase() {
@Test
fun `should still process results after multiple failures`() {
val malformedResults = GroupedResultsXmlLoader().passingGroupedResults().replace("testsuite", "")
val successfulResults = GroupedResultsXmlLoader().passingGroupedResults()

withTestApplication(::createTestApplication) {
(1..10).forEach { _ ->
handleRequest(HttpMethod.Post, "/groupedResults") {
addHeader(HttpHeaders.ContentType, "application/json")
setBody(malformedResults)
}.apply {
val resultsResponse = objectMapper.readValue(response.content, SaveResultsResponse::class.java)

val publicId = resultsResponse.id
assertNotNull(publicId)

await until { resultsProcessingDao.fetchOneByPublicId(publicId).status == ResultsProcessingStatus.ERROR.name }
}
}

(1..10).forEach { _ ->
handleRequest(HttpMethod.Post, "/groupedResults") {
addHeader(HttpHeaders.ContentType, "application/json")
setBody(successfulResults)
}.apply {
val resultsResponse = objectMapper.readValue(response.content, SaveResultsResponse::class.java)

val publicId = resultsResponse.id
assertNotNull(publicId)

await until { resultsProcessingDao.fetchOneByPublicId(publicId).status == ResultsProcessingStatus.SUCCESS.name }
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import io.ktor.http.*
import io.ktor.server.testing.*
import io.ktor.util.KtorExperimentalAPI
import java.math.BigDecimal
import kotlin.test.*
import kotlin.test.assertNotNull
import org.awaitility.kotlin.await
import org.awaitility.kotlin.untilNotNull
import org.junit.jupiter.api.Test
import projektor.ApplicationTestCase
import projektor.server.api.results.SaveResultsResponse
import strikt.api.expectThat
Expand Down
Loading

0 comments on commit dfa5e3f

Please sign in to comment.