avito-android

Форк
0
261 строка · 9.5 Кб
1
package com.avito.instrumentation
2

3
import com.avito.android.build_verdict.BuildVerdictTask
4
import com.avito.android.build_verdict.span.SpannedString
5
import com.avito.android.build_verdict.span.SpannedString.Companion.link
6
import com.avito.android.build_verdict.span.SpannedString.Companion.multiline
7
import com.avito.android.getApk
8
import com.avito.android.getApkOrThrow
9
import com.avito.android.stats.StatsDConfig
10
import com.avito.gradle.worker.inMemoryWork
11
import com.avito.instrumentation.configuration.Experiments
12
import com.avito.instrumentation.internal.RunnerInputDumper
13
import com.avito.logger.GradleLoggerPlugin
14
import com.avito.runner.config.InstrumentationConfigurationCacheableData
15
import com.avito.runner.config.InstrumentationConfigurationDataFactory
16
import com.avito.runner.config.RunnerInputParams
17
import com.avito.runner.config.RunnerReportConfig
18
import com.avito.runner.finalizer.verdict.InstrumentationTestsTaskVerdict
19
import com.avito.runner.model.InstrumentationParameters
20
import com.avito.runner.scheduler.runner.model.ExecutionParameters
21
import com.avito.runner.scheduler.runner.scheduler.TestSchedulerFactoryProvider
22
import com.avito.runner.scheduler.runner.scheduler.TestSchedulerResult
23
import com.avito.runner.scheduler.suite.filter.ImpactAnalysisResult
24
import com.avito.test.model.DeviceName
25
import com.avito.utils.BuildFailer
26
import com.avito.utils.gradle.KubernetesCredentials
27
import com.google.gson.Gson
28
import com.google.gson.GsonBuilder
29
import org.gradle.api.DefaultTask
30
import org.gradle.api.file.DirectoryProperty
31
import org.gradle.api.file.RegularFileProperty
32
import org.gradle.api.model.ObjectFactory
33
import org.gradle.api.provider.MapProperty
34
import org.gradle.api.provider.Property
35
import org.gradle.api.provider.SetProperty
36
import org.gradle.api.tasks.CacheableTask
37
import org.gradle.api.tasks.Input
38
import org.gradle.api.tasks.InputDirectory
39
import org.gradle.api.tasks.InputFile
40
import org.gradle.api.tasks.Internal
41
import org.gradle.api.tasks.Optional
42
import org.gradle.api.tasks.OutputDirectory
43
import org.gradle.api.tasks.PathSensitive
44
import org.gradle.api.tasks.PathSensitivity
45
import org.gradle.api.tasks.TaskAction
46
import org.gradle.workers.WorkerExecutor
47
import java.time.Duration
48
import javax.inject.Inject
49

50
@CacheableTask
51
public abstract class InstrumentationTestsTask @Inject constructor(
52
    objects: ObjectFactory,
53
    private val workerExecutor: WorkerExecutor
54
) : DefaultTask(), BuildVerdictTask {
55

56
    @get:Optional
57
    @get:InputDirectory
58
    @get:PathSensitive(PathSensitivity.RELATIVE)
59
    public abstract val application: DirectoryProperty
60

61
    @get:Optional
62
    @get:Input
63
    public abstract val applicationPackageName: Property<String>
64

65
    @get:InputDirectory
66
    @get:PathSensitive(PathSensitivity.RELATIVE)
67
    public abstract val testApplication: DirectoryProperty
68

69
    @get:Input
70
    public abstract val testApplicationPackageName: Property<String>
71

72
    @get:Optional
73
    @get:Input
74
    public abstract val testArtifactsDirectoryPackageName: Property<String>
75

76
    @get:Input
77
    public abstract val runOnlyChangedTests: Property<Boolean>
78

79
    @get:Optional
80
    @get:InputFile
81
    @get:PathSensitive(PathSensitivity.RELATIVE)
82
    public abstract val changedTests: RegularFileProperty
83

84
    @get:Optional
85
    @get:InputFile
86
    @get:PathSensitive(PathSensitivity.RELATIVE)
87
    public abstract val applicationProguardMapping: RegularFileProperty
88

89
    @get:Optional
90
    @get:InputFile
91
    @get:PathSensitive(PathSensitivity.RELATIVE)
92
    public abstract val testProguardMapping: RegularFileProperty
93

94
    @get:Internal
95
    public abstract val buildId: Property<String>
96

97
    @get:Internal
98
    public abstract val buildType: Property<String>
99

100
    @get:Internal
101
    public abstract val gitCommit: Property<String>
102

103
    @get:Internal
104
    public abstract val gitBranch: Property<String>
105

106
    @get:Input
107
    public abstract val experiments: Property<Experiments>
108

109
    @get:Input
110
    public abstract val suppressFailure: Property<Boolean>
111

112
    @get:Input
113
    public abstract val suppressFlaky: Property<Boolean>
114

115
    @get:Input
116
    public abstract val instrumentationConfiguration: Property<InstrumentationConfigurationCacheableData>
117

118
    @get:Internal
119
    public abstract val mergedInstrumentationParams: MapProperty<String, String>
120

121
    @get:Internal
122
    public abstract val reportConfig: Property<RunnerReportConfig>
123

124
    @get:Internal
125
    public abstract val targetInstrumentationParams: MapProperty<DeviceName, InstrumentationParameters>
126

127
    @get:Input
128
    public abstract val instrumentationRunner: Property<String>
129

130
    @get:Input
131
    public abstract val logcatTags: SetProperty<String>
132

133
    @get:Input
134
    public abstract val enableDeviceDebug: Property<Boolean>
135

136
    @get:Input
137
    public abstract val gradleTestKitRun: Property<Boolean>
138

139
    @get:Input
140
    public abstract val projectName: Property<String>
141

142
    @get:Internal
143
    public abstract val kubernetesCredentials: Property<KubernetesCredentials>
144

145
    @get:Internal
146
    public abstract val kubernetesHttpTries: Property<Int>
147

148
    @get:Internal
149
    public abstract val buildFailer: Property<BuildFailer>
150

151
    @get:Internal
152
    public abstract val statsDConfig: Property<StatsDConfig>
153

154
    @get:Internal
155
    public abstract val adbPullTimeout: Property<Duration>
156

157
    @get:OutputDirectory
158
    public abstract val output: DirectoryProperty
159

160
    @get:OutputDirectory
161
    @get:Optional
162
    public abstract val macrobenchmarkOutputDirectory: DirectoryProperty
163

164
    private val verdictFile = objects.fileProperty().convention(output.file("verdict.json"))
165

166
    @get:Internal
167
    override val verdict: SpannedString
168
        get() {
169
            val verdictFile = verdictFile.asFile.get()
170
            return if (verdictFile.exists()) {
171
                val gson: Gson = GsonBuilder().setPrettyPrinting().create()
172
                val verdictRaw = verdictFile.reader()
173
                val verdict = gson.fromJson(verdictRaw, InstrumentationTestsTaskVerdict::class.java)
174
                return multiline(
175
                    lines = listOf(link(verdict.reportUrl, verdict.title)) +
176
                        verdict.problemTests.map { test ->
177
                            link(test.testUrl, test.title)
178
                        }
179
                )
180
            } else {
181
                SpannedString("Can't find verdict file $verdictFile")
182
            }
183
        }
184

185
    @TaskAction
186
    public fun doWork() {
187
        val configuration = instrumentationConfiguration.get()
188
        val experiments = experiments.get()
189
        val output = output.get().asFile
190

191
        val testRunParams = RunnerInputParams(
192
            mainApk = requireNotNull(application.orNull?.getApk()) {
193
                "Unable to create valid RunnerInputParams - mainApk cannot be null."
194
            },
195
            testApk = testApplication.get().getApkOrThrow(),
196
            instrumentationConfiguration = InstrumentationConfigurationDataFactory(
197
                instrumentationConfigurationCacheableData = configuration,
198
                mergedInstrumentationParams = InstrumentationParameters(mergedInstrumentationParams.get()),
199
                reportConfig = reportConfig.get(),
200
                targetInstrumentationParams = targetInstrumentationParams.get(),
201
            ).create(),
202
            executionParameters = ExecutionParameters(
203
                applicationPackageName.get(),
204
                testApplicationPackageName.get(),
205
                testArtifactsDirectoryPackageName.getOrElse(applicationPackageName.get()),
206
                instrumentationRunner.get(),
207
                logcatTags.get(),
208
            ),
209
            buildId = buildId.get(),
210
            buildType = buildType.get(),
211
            kubernetesCredentials = requireNotNull(kubernetesCredentials.orNull) {
212
                "you need to provide kubernetesCredentials"
213
            },
214
            kubernetesHttpTries = kubernetesHttpTries.get(),
215
            deviceDebug = enableDeviceDebug.get(),
216
            projectName = projectName.get(),
217
            suppressFailure = suppressFailure.get(),
218
            suppressFlaky = suppressFlaky.get(),
219
            impactAnalysisResult = ImpactAnalysisResult.create(
220
                runOnlyChangedTests = runOnlyChangedTests.get(),
221
                changedTestsFile = changedTests.asFile.orNull
222
            ),
223
            outputDir = output,
224
            verdictFile = verdictFile.get().asFile,
225
            statsDConfig = statsDConfig.get(),
226
            proguardMappings = listOf(
227
                applicationProguardMapping,
228
                testProguardMapping
229
            ).mapNotNull { it.orNull?.asFile },
230
            saveTestArtifactsToOutputs = experiments.saveTestArtifactsToOutputs,
231
            useLegacyExtensionsV1Beta = experiments.useLegacyExtensionsV1Beta,
232
            adbPullTimeout = adbPullTimeout.get(),
233
            macrobenchmarkOutputDir = macrobenchmarkOutputDirectory.orNull?.asFile,
234
        )
235

236
        val isGradleTestKitRun = gradleTestKitRun.get()
237

238
        RunnerInputDumper(output).dumpInput(
239
            input = testRunParams,
240
            isGradleTestKitRun = isGradleTestKitRun
241
        )
242

243
        if (!isGradleTestKitRun) {
244
            val loggerFactory = GradleLoggerPlugin.provideLoggerFactory(this).get()
245
            workerExecutor.inMemoryWork {
246
                when (
247
                    val result = TestSchedulerFactoryProvider(loggerFactory)
248
                        .provide(testRunParams)
249
                        .create()
250
                        .schedule()
251
                ) {
252
                    TestSchedulerResult.Ok -> {
253
                        // do nothing
254
                    }
255

256
                    is TestSchedulerResult.Failure -> buildFailer.get().failBuild(result.message)
257
                }
258
            }
259
        }
260
    }
261
}
262

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.