Skip to content

Commit

Permalink
Merge pull request #68 from Malinskiy/refactoring/junit_output_genera…
Browse files Browse the repository at this point in the history
…tion

Refactoring/junit output generation
  • Loading branch information
tagantroy authored Jul 17, 2018
2 parents 3e03522 + d1b8535 commit a25c8d3
Show file tree
Hide file tree
Showing 10 changed files with 67 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ interface Device {
fun execute(configuration: Configuration,
devicePoolId: DevicePoolId,
testBatch: TestBatch,
tracker: Analytics,
deferred: CompletableDeferred<TestBatchResults>,
progressReporter: ProgressReporter)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import mu.KotlinLogging

class DevicePoolActor(private val poolId: DevicePoolId,
private val configuration: Configuration,
private val analytics: Analytics,
analytics: Analytics,
tests: Collection<Test>,
private val progressReporter: ProgressReporter,
parent: Job) : Actor<DevicePoolMessage>(parent = parent) {
Expand Down Expand Up @@ -99,7 +99,7 @@ class DevicePoolActor(private val poolId: DevicePoolId,

private suspend fun addDevice(device: Device) {
logger.debug { "add device ${device.serialNumber}" }
val actor = DeviceActor(poolId, this, configuration, device, analytics, progressReporter, poolJob)
val actor = DeviceActor(poolId, this, configuration, device, progressReporter, poolJob)
devices[device.serialNumber] = actor
actor.send(DeviceEvent.Initialize)
}
Expand Down
37 changes: 25 additions & 12 deletions core/src/main/kotlin/com/malinskiy/marathon/execution/QueueActor.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.malinskiy.marathon.execution

import com.malinskiy.marathon.actor.Actor
import com.malinskiy.marathon.analytics.Analytics
import com.malinskiy.marathon.analytics.metrics.MetricsProvider
import com.malinskiy.marathon.device.Device
import com.malinskiy.marathon.device.DevicePoolId
Expand All @@ -16,7 +17,7 @@ import java.util.*

class QueueActor(configuration: Configuration,
private val testShard: TestShard,
metricsProvider: MetricsProvider,
private val analytics: Analytics,
private val pool: SendChannel<FromQueue>,
private val poolId: DevicePoolId,
private val progressReporter: ProgressReporter,
Expand All @@ -26,7 +27,7 @@ class QueueActor(configuration: Configuration,

private val sorting = configuration.sortingStrategy

private val queue: Queue<Test> = PriorityQueue<Test>(sorting.process(metricsProvider))
private val queue: Queue<Test> = PriorityQueue<Test>(sorting.process(analytics))
private val batching = configuration.batchingStrategy
private val retry = configuration.retryStrategy

Expand Down Expand Up @@ -62,43 +63,55 @@ class QueueActor(configuration: Configuration,
val failed = results.failed
logger.debug { "handle test results ${device.serialNumber}" }
if (finished.isNotEmpty()) {
handleFinishedTests(finished)
handleFinishedTests(finished, device)
}
if (failed.isNotEmpty()) {
handleFailedTests(poolId, failed, device)
handleFailedTests(failed, device)
}
activeBatches.remove(device)
onRequestBatch(device)
}

private fun onReturnBatch(device: Device, batch: TestBatch) {

queue.addAll(batch.tests)
returnTests(batch.tests)
activeBatches.remove(device)
}

private fun returnTests(tests: Collection<Test>) {
queue.addAll(tests)
}

private fun onTerminate() {
close()
}

private fun handleFinishedTests(finished: Collection<Test>) {
finished.filter { testShard.flakyTests.contains(it) }.let {
private fun handleFinishedTests(finished: Collection<TestResult>, device: Device) {
finished.filter { testShard.flakyTests.contains(it.test) }.let {
val oldSize = queue.size
queue.removeAll(it)
queue.removeAll(it.map { it.test })
progressReporter.removeTests(poolId, oldSize - queue.size)
}
finished.forEach {
analytics.trackTestResult(poolId, device, it)
}
}

private suspend fun handleFailedTests(poolId: DevicePoolId,
failed: Collection<Test>,
private suspend fun handleFailedTests(failed: Collection<TestResult>,
device: Device) {
logger.debug { "handle failed tests ${device.serialNumber}" }
val retryList = retry.process(poolId, failed, testShard)
val retryList = retry.process(poolId, failed.map { it.test }, testShard)

progressReporter.addTests(poolId, retryList.size)
queue.addAll(retryList)
if (retryList.isNotEmpty()) {
pool.send(FromQueue.Notify)
}

failed.filterNot {
retryList.contains(it.test)
}.forEach {
analytics.trackTestResult(poolId, device, it)
}
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ import com.malinskiy.marathon.device.Device
import com.malinskiy.marathon.test.Test

data class TestBatchResults(val device: Device,
val finished: Collection<Test>,
val failed: Collection<Test>)
val finished: Collection<TestResult>,
val failed: Collection<TestResult>)
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@ package com.malinskiy.marathon.execution.device

import com.malinskiy.marathon.actor.Actor
import com.malinskiy.marathon.actor.StateMachine
import com.malinskiy.marathon.analytics.Analytics
import com.malinskiy.marathon.device.Device
import com.malinskiy.marathon.device.DevicePoolId
import com.malinskiy.marathon.execution.Configuration
import com.malinskiy.marathon.execution.DevicePoolMessage
import com.malinskiy.marathon.execution.DevicePoolMessage.FromDevice.RequestNextBatch
import com.malinskiy.marathon.execution.QueueMessage
import com.malinskiy.marathon.execution.TestBatchResults
import com.malinskiy.marathon.execution.progress.ProgressReporter
import com.malinskiy.marathon.test.TestBatch
Expand All @@ -25,7 +23,6 @@ class DeviceActor(private val devicePoolId: DevicePoolId,
private val pool: SendChannel<DevicePoolMessage>,
private val configuration: Configuration,
private val device: Device,
private val analytics: Analytics,
private val progressReporter: ProgressReporter,
parent: Job) : Actor<DeviceEvent>(parent = parent) {

Expand Down Expand Up @@ -151,7 +148,7 @@ class DeviceActor(private val devicePoolId: DevicePoolId,
private fun executeBatch(batch: TestBatch, result: CompletableDeferred<TestBatchResults>) {
logger.debug { "executeBatch" }
job = async(context, parent = deviceJob) {
device.execute(configuration, devicePoolId, batch, analytics, result, progressReporter)
device.execute(configuration, devicePoolId, batch, result, progressReporter)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.malinskiy.marathon.device

import com.malinskiy.marathon.analytics.Analytics
import com.malinskiy.marathon.execution.Configuration
import com.malinskiy.marathon.execution.TestBatchResults
import com.malinskiy.marathon.execution.progress.ProgressReporter
Expand All @@ -15,7 +14,7 @@ class DeviceStub(override var operatingSystem: OperatingSystem = OperatingSystem
override val model: String = "model",
override val manufacturer: String = "manufacturer",
override val deviceFeatures: Collection<DeviceFeature> = emptyList()) : Device {
override fun execute(configuration: Configuration, devicePoolId: DevicePoolId, testBatch: TestBatch, tracker: Analytics, deferred: CompletableDeferred<TestBatchResults>, progressReporter: ProgressReporter) {
override fun execute(configuration: Configuration, devicePoolId: DevicePoolId, testBatch: TestBatch, deferred: CompletableDeferred<TestBatchResults>, progressReporter: ProgressReporter) {
}

override fun prepare(configuration: Configuration) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,9 @@ class AndroidDevice(val ddmsDevice: IDevice) : Device {
override fun execute(configuration: Configuration,
devicePoolId: DevicePoolId,
testBatch: TestBatch,
tracker: Analytics,
deferred: CompletableDeferred<TestBatchResults>,
progressReporter: ProgressReporter) {
AndroidDeviceTestRunner(this@AndroidDevice, tracker).execute(configuration, devicePoolId, testBatch, deferred, progressReporter)
AndroidDeviceTestRunner(this@AndroidDevice).execute(configuration, devicePoolId, testBatch, deferred, progressReporter)
}

override fun prepare(configuration: Configuration) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@ import com.android.ddmlib.AdbCommandRejectedException
import com.android.ddmlib.ShellCommandUnresponsiveException
import com.android.ddmlib.TimeoutException
import com.android.ddmlib.testrunner.RemoteAndroidTestRunner
import com.malinskiy.marathon.analytics.Analytics
import com.malinskiy.marathon.android.AndroidDevice
import com.malinskiy.marathon.android.ApkParser
import com.malinskiy.marathon.android.executor.listeners.AnalyticsListener
import com.malinskiy.marathon.android.executor.listeners.CompositeTestRunListener
import com.malinskiy.marathon.android.executor.listeners.DebugTestRunListener
import com.malinskiy.marathon.android.executor.listeners.LogCatListener
Expand All @@ -27,8 +25,7 @@ import mu.KotlinLogging
import java.io.IOException
import java.util.concurrent.TimeUnit

class AndroidDeviceTestRunner(private val device: AndroidDevice,
private val analytics: Analytics) {
class AndroidDeviceTestRunner(private val device: AndroidDevice) {

private val logger = KotlinLogging.logger("AndroidDeviceTestRunner")

Expand All @@ -55,7 +52,6 @@ class AndroidDeviceTestRunner(private val device: AndroidDevice,
ScreenRecorderTestRunListener(fileManager, devicePoolId, device),
DebugTestRunListener(device.ddmsDevice),
ProgressTestRunListener(device, devicePoolId, progressReporter),
AnalyticsListener(device, devicePoolId, analytics),
LogCatListener(device, devicePoolId, LogWriter(fileManager)))
)
try {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package com.malinskiy.marathon.android.executor.listeners

import com.android.ddmlib.testrunner.TestIdentifier
import com.android.ddmlib.testrunner.TestResult
import com.malinskiy.marathon.android.toMarathonStatus
import com.malinskiy.marathon.android.toTest
import com.malinskiy.marathon.device.Device
import com.malinskiy.marathon.device.toDeviceInfo
import com.malinskiy.marathon.execution.TestBatchResults
import com.malinskiy.marathon.test.Test
import com.malinskiy.marathon.test.TestBatch
import com.malinskiy.marathon.execution.TestResult
import com.malinskiy.marathon.execution.TestStatus
import kotlinx.coroutines.experimental.CompletableDeferred
import com.android.ddmlib.testrunner.TestRunResult as DdmLibTestRunResult
import com.android.ddmlib.testrunner.TestResult as DdmLibTestResult

class TestRunResultsListener(private val testBatch: TestBatch,
private val device: Device,
Expand All @@ -16,23 +21,42 @@ class TestRunResultsListener(private val testBatch: TestBatch,
val results = runResult.testResults
val tests = testBatch.tests.associateBy { it.identifier() }

val finished = tests.filter {
results[it.key]?.isSuccessful() ?: false
}.values
val testResults = runResult.testResults.map {
it.toTestResult(device)
}

val failed = tests.filterNot {
results[it.key]?.isSuccessful() ?: false
}.values
val finished = testResults.filter {
results[it.test.identifier()]?.isSuccessful() ?: false
}

deferred.complete(TestBatchResults(device, finished, failed))
val failed = testResults.filterNot {
results[it.test.identifier()]?.isSuccessful() ?: false
}

val notExecuted = tests.filterNot {
results.containsKey(it.key)
}.values.map {
TestResult(it, device.toDeviceInfo(), TestStatus.INCOMPLETE, 0, 0, null)
}

deferred.complete(TestBatchResults(device, finished, failed + notExecuted))
}

fun Map.Entry<TestIdentifier, DdmLibTestResult>.toTestResult(device: Device): TestResult {
return TestResult(test = key.toTest(),
device = device.toDeviceInfo(),
status = value.status.toMarathonStatus(),
startTime = value.startTime,
endTime = value.endTime,
stacktrace = value.stackTrace)
}


private fun Test.identifier(): TestIdentifier {
return TestIdentifier("$pkg.$clazz", method)
}

private fun TestResult.isSuccessful() =
status == TestResult.TestStatus.PASSED || status == TestResult.TestStatus.IGNORED
private fun DdmLibTestResult.isSuccessful() =
status == DdmLibTestResult.TestStatus.PASSED || status == DdmLibTestResult.TestStatus.IGNORED

}

0 comments on commit a25c8d3

Please sign in to comment.