blob: 0002e40478fdd33ec760c2c18306e29672648f68 [file] [log] [blame]
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.wm.flicker.service.rules
import android.platform.test.rule.TestWatcher
import androidx.test.platform.app.InstrumentationRegistry
import com.android.server.wm.flicker.Utils
import com.android.server.wm.flicker.getDefaultFlickerOutputDir
import com.android.server.wm.flicker.service.FlickerServiceResultsCollector
import com.android.server.wm.flicker.service.FlickerServiceTracesCollector
import com.android.server.wm.flicker.service.IFlickerServiceResultsCollector
import com.android.server.wm.traces.common.CrossPlatform
import com.android.server.wm.traces.common.FLICKER_TAG
import com.android.server.wm.traces.common.TimestampFactory
import com.android.server.wm.traces.parser.ANDROID_LOGGER
import org.junit.AssumptionViolatedException
import org.junit.runner.Description
import org.junit.runner.notification.Failure
/**
* A test rule that runs Flicker as a Service on the tests this rule is applied to.
*
* Note there are performance implications to using this test rule in tests. Tracing will be enabled
* during the test which will slow down everything. So if the test is performance critical then an
* alternative should be used.
*
* @see TODO for examples on how to use this test rule in your own tests
*/
open class FlickerServiceRule
@JvmOverloads
constructor(
private val metricsCollector: IFlickerServiceResultsCollector =
FlickerServiceResultsCollector(
tracesCollector = FlickerServiceTracesCollector(getDefaultFlickerOutputDir()),
instrumentation = InstrumentationRegistry.getInstrumentation()
),
// defaults to true
private val failTestOnFaasFailure: Boolean =
InstrumentationRegistry.getArguments().getString("faas:blocking")?.let { it.toBoolean() }
?: true
) : TestWatcher() {
init {
CrossPlatform.setLogger(ANDROID_LOGGER)
.setTimestampFactory(TimestampFactory { Utils.formatRealTimestamp(it) })
}
/** Invoked when a test is about to start */
public override fun starting(description: Description) {
CrossPlatform.log.i(LOG_TAG, "Test starting $description")
metricsCollector.testStarted(description)
}
/** Invoked when a test succeeds */
public override fun succeeded(description: Description) {
CrossPlatform.log.i(LOG_TAG, "Test succeeded $description")
}
/** Invoked when a test fails */
public override fun failed(e: Throwable?, description: Description) {
CrossPlatform.log.e(LOG_TAG, "$description test failed with $e")
metricsCollector.testFailure(Failure(description, e))
}
/** Invoked when a test is skipped due to a failed assumption. */
public override fun skipped(e: AssumptionViolatedException, description: Description) {
CrossPlatform.log.i(LOG_TAG, "Test skipped $description with $e")
metricsCollector.testSkipped(description)
}
/** Invoked when a test method finishes (whether passing or failing) */
public override fun finished(description: Description) {
CrossPlatform.log.i(LOG_TAG, "Test finished $description")
metricsCollector.testFinished(description)
if (metricsCollector.executionErrors.isNotEmpty()) {
for (executionError in metricsCollector.executionErrors) {
CrossPlatform.log.e(LOG_TAG, "FaaS reported execution errors", executionError)
}
throw metricsCollector.executionErrors[0]
}
if (failTestOnFaasFailure && metricsCollector.testContainsFlicker(description)) {
throw metricsCollector.resultsForTest(description).first { it.failed }.assertionError
?: error("Unexpectedly missing assertion error")
}
}
companion object {
const val LOG_TAG = "$FLICKER_TAG-ServiceRule"
}
}