Skip to content

numShards, shardIndex support #270

@jerry-jeon

Description

@jerry-jeon

The sharding feature that's available in AndroidJunitRunner is not working in AndroidJunit5Runner.
Is there any way to achieve it? I tried to do it through the ExecutionCondition extension, but it makes the test "ignored". I want to make the runner doesn't recognize tests that aren't included in the specific sharding.

I briefly changed the code by refering the AndroidJunitRunner code and it's working well. But I am not sure it's the right way to do it.

internal fun createRunnerParams(testClass: Class<*>): AndroidJUnit5RunnerParams {
    val instrumentation = InstrumentationRegistry.getInstrumentation()
    val arguments = InstrumentationRegistry.getArguments()

    // Parse environment variables & pass them to the JVM
    val environmentVariables = arguments.getString(ARG_ENVIRONMENT_VARIABLES)
        ?.run { PropertiesParser.fromString(this) }
        ?: emptyMap()

    // Parse system properties & pass them to the JVM
    val systemProperties = arguments.getString(ARG_SYSTEM_PROPERTIES)
        ?.run { PropertiesParser.fromString(this) }
        ?: emptyMap()

    // Parse configuration parameters
    val configurationParameters = arguments.getString(ARG_CONFIGURATION_PARAMETERS)
        ?.run { PropertiesParser.fromString(this) }
        ?: emptyMap()

    // Parse the selectors to use from what's handed to the runner.
    val selectors = ParsedSelectors.fromBundle(testClass, arguments)

    // The user may apply test filters to their instrumentation tests through the Gradle plugin's DSL,
    // which aren't subject to the filtering imposed through adb.
    // A special resource file may be looked up at runtime, containing
    // the filters to apply by the AndroidJUnit5 runner.
    val filters = mutableListOf<Filter<*>>()
    val contextFilters = GeneratedFilters.fromContext(instrumentation.context)
    filters.addAll(contextFilters)

    class ShardingFilter(val numShards: Int, val shardIndex: Int) : PostDiscoveryFilter {
        override fun apply(descriptor: TestDescriptor): FilterResult {
            if (descriptor.isTest) {
                val remainder = abs(descriptor.hashCode()) % numShards
                val runningShard = remainder == shardIndex
                return if (runningShard) {
                    FilterResult.included(null)
                } else {
                    FilterResult.excluded("excluded")
                }
            }

            for (each in descriptor.children) {
                return if (apply(each).included()) {
                    FilterResult.included(null)
                } else {
                    FilterResult.excluded("excluded")
                }
            }

            return FilterResult.excluded("excluded")
        }
    }

    val numShards = arguments.getString("numShards")?.toInt() ?: -1
    val shardIndex = arguments.getString("shardIndex")?.toInt() ?: -1
    if (numShards > 0 && shardIndex >= 0 && shardIndex < numShards) {
        filters.add(ShardingFilter(numShards, shardIndex))
    }

    return AndroidJUnit5RunnerParams(
        selectors,
        filters,
        environmentVariables,
        systemProperties,
        configurationParameters
    )
}

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions