1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.tools.metalava.model.testsuite
18 
19 import com.android.tools.metalava.model.junit4.CustomizableParameterizedRunner
20 import com.android.tools.metalava.model.testing.BaseModelProviderRunner
21 import com.android.tools.metalava.model.testing.CodebaseCreatorConfig
22 import com.android.tools.metalava.model.testing.CodebaseCreatorConfigAware
23 import java.util.ServiceLoader
24 import kotlin.test.fail
25 import org.junit.runners.Parameterized
26 
27 /**
28  * A special [CustomizableParameterizedRunner] for use with the model test suite tests.
29  *
30  * This provides the list of [CodebaseCreatorConfig] constructed from the [ModelSuiteRunner]
31  * accessible through the [ServiceLoader]. If the test provides its own arguments using
32  * [Parameterized.Parameters] then this will compute the cross produce of those arguments with the
33  * [CodebaseCreatorConfig]. That will ensure that every set of arguments provided by the test clas s
34  * will be run with every [ModelSuiteRunner] available.
35  *
36  * The [CodebaseCreatorConfig] is injected into the test through
37  * [CodebaseCreatorConfigAware.codebaseCreatorConfig] and not through a field annotated with
38  * [Parameterized.Parameter]. That means that switching a class that is already [Parameterized] to
39  * use this instead does not affect any existing [Parameterized.Parameter] fields.
40  */
41 class ModelTestSuiteRunner(clazz: Class<*>) :
42     BaseModelProviderRunner<ModelSuiteRunner, CodebaseCreatorConfigAware<ModelSuiteRunner>>(
43         clazz = clazz,
<lambda>null44         codebaseCreatorConfigsGetter = { getModelSuiteRunners() },
45         baselineResourcePath = ModelTestSuiteBaseline.RESOURCE_PATH,
46     ) {
47 
48     companion object {
getModelSuiteRunnersnull49         private fun getModelSuiteRunners(): List<CodebaseCreatorConfig<ModelSuiteRunner>> {
50             val loader = ServiceLoader.load(ModelSuiteRunner::class.java)
51             val modelSuiteRunners = loader.toList()
52             if (modelSuiteRunners.isEmpty()) {
53                 fail("No runners found")
54             }
55             val runner = modelSuiteRunners.single()
56 
57             return runner.testConfigurations.map {
58                 CodebaseCreatorConfig(
59                     creator = runner,
60                     inputFormat = it.inputFormat,
61                     modelOptions = it.modelOptions,
62                     // There is only a single runner for a single provider so ignore the
63                     // provider name.
64                     includeProviderNameInTestName = false,
65                     // Only include the input format in the test name if the runner supports
66                     // more than one.
67                     includeInputFormatInTestName = runner.supportedInputFormats.size > 1,
68                 )
69             }
70         }
71     }
72 }
73