@@ -33,9 +33,12 @@ import kotlinx.serialization.json.jsonArray
3333import kotlinx.serialization.json.jsonObject
3434import kotlinx.serialization.json.jsonPrimitive
3535import org.gradle.internal.Pair
36+ import org.slf4j.Logger
37+ import org.slf4j.LoggerFactory
3638
3739@SuppressWarnings(" NewApi" )
3840class UnitTestReport (private val apiToken : String ) {
41+ private val LOG : Logger = LoggerFactory .getLogger(" firebase-test-report" )
3942 private val client: HttpClient =
4043 HttpClient .newBuilder().connectTimeout(Duration .ofSeconds(10 )).build()
4144
@@ -73,7 +76,7 @@ class UnitTestReport(private val apiToken: String) {
7376 }
7477
7578 private fun outputReport (commits : List <ReportCommit >) {
76- val reports: MutableList <TestReport > = ArrayList ()
79+ val reports: MutableList <TestReport > = mutableListOf ()
7780 for (commit in commits) {
7881 reports.addAll(parseTestReports(commit.sha))
7982 }
@@ -109,7 +112,7 @@ class UnitTestReport(private val apiToken: String) {
109112 val commits = reports.map(TestReport ::commit).distinct()
110113 var sdks = reports.map(TestReport ::name).distinct().sorted()
111114 val lookup = reports.associateBy({ report -> Pair .of(report.name, report.commit) })
112- val successPercentage: MutableMap <String , Int > = HashMap ()
115+ val successPercentage: MutableMap <String , Int > = hashMapOf ()
113116 var passingSdks = 0
114117 // Get success percentage
115118 for (sdk in sdks) {
@@ -140,7 +143,7 @@ class UnitTestReport(private val apiToken: String) {
140143 }
141144 val output = StringBuilder (" | |" )
142145 for (commit in commits) {
143- val rc = commitLookup.get( commit)
146+ val rc = commitLookup[ commit]
144147 output.append(" " )
145148 if (rc != null && rc.pr != - 1 ) {
146149 output.append(" [#${rc.pr} ](https://github.com/firebase/firebase-android-sdk/pull/${rc.pr} )" )
@@ -154,7 +157,7 @@ class UnitTestReport(private val apiToken: String) {
154157 output.append(" :---: |" .repeat(commits.size))
155158 output.append(" :--- |" )
156159 for (sdk in sdks) {
157- output.append(" \n | " ).append( sdk).append( " |" )
160+ output.append(" \n | $ sdk |" )
158161 for (commit in commits) {
159162 if (lookup.containsKey(Pair .of(sdk, commit))) {
160163 val report: TestReport = lookup[Pair .of(sdk, commit)]!!
@@ -174,38 +177,38 @@ class UnitTestReport(private val apiToken: String) {
174177 if (successChance == 100 ) {
175178 output.append(" ✅ 100%" )
176179 } else {
177- output.append(" ⛔ " ).append( successChance).append( " %" )
180+ output.append(" ⛔ $ successChance %" )
178181 }
179182 output.append(" |" )
180183 }
181184 output.append(" \n " )
182185 if (passingSdks > 0 ) {
183- output.append(" \n *+" ).append( passingSdks).append( " passing SDKs* \n " )
186+ output.append(" \n *+$ passingSdks passing SDKs" )
184187 }
185188 return output.toString()
186189 }
187190
188191 private fun parseTestReports (commit : String ): List <TestReport > {
189- val runs = request(" actions/runs?head_sha=" + commit)
192+ val runs = request(" actions/runs?head_sha=$ commit" )
190193 for (el in runs[" workflow_runs" ] as JsonArray ) {
191194 val run = el as JsonObject
192195 val name = run[" name" ]!! .jsonPrimitive.content
193196 if (name == " CI Tests" ) {
194197 return parseCITests(run[" id" ]!! .jsonPrimitive.content, commit)
195198 }
196199 }
197- return listOf ()
200+ return emptyList ()
198201 }
199202
200203 private fun parseCITests (id : String , commit : String ): List <TestReport > {
201- val reports: MutableList <TestReport > = ArrayList ()
202- val jobs = request(" actions/runs/" + id + " /jobs" )
204+ val reports: MutableList <TestReport > = mutableListOf ()
205+ val jobs = request(" actions/runs/$id /jobs" )
203206 for (el in jobs[" jobs" ] as JsonArray ) {
204207 val job = el as JsonObject
205- val jid = job[" name" ]!! .jsonPrimitive.content
206- if (jid .startsWith(" Unit Tests (:" )) {
208+ val jobName = job[" name" ]!! .jsonPrimitive.content
209+ if (jobName .startsWith(" Unit Tests (:" )) {
207210 reports.add(parseJob(TestReport .Type .UNIT_TEST , job, commit))
208- } else if (jid .startsWith(" Instrumentation Tests (:" )) {
211+ } else if (jobName .startsWith(" Instrumentation Tests (:" )) {
209212 reports.add(parseJob(TestReport .Type .INSTRUMENTATION_TEST , job, commit))
210213 }
211214 }
@@ -217,17 +220,19 @@ class UnitTestReport(private val apiToken: String) {
217220 job[" name" ]!!
218221 .jsonPrimitive
219222 .content
220- .split(" \\ (:" .toRegex() )
223+ .split(" (:" )
221224 .dropLastWhile { it.isEmpty() }
222225 .toTypedArray()[1 ]
223226 name = name.substring(0 , name.length - 1 ) // Remove trailing ")"
224- var status = TestReport . Status . OTHER
227+ val status =
225228 if (job[" status" ]!! .jsonPrimitive.content == " completed" ) {
226229 if (job[" conclusion" ]!! .jsonPrimitive.content == " success" ) {
227- status = TestReport .Status .SUCCESS
230+ TestReport .Status .SUCCESS
228231 } else {
229- status = TestReport .Status .FAILURE
232+ TestReport .Status .FAILURE
230233 }
234+ } else {
235+ TestReport .Status .OTHER
231236 }
232237 val url = job[" html_url" ]!! .jsonPrimitive.content
233238 return TestReport (name, type, status, commit, url)
@@ -236,8 +241,7 @@ class UnitTestReport(private val apiToken: String) {
236241 private fun generateGraphQLQuery (commitCount : Int ): JsonObject {
237242 return JsonObject (
238243 mapOf (
239- Pair (
240- " query" ,
244+ " query" to
241245 JsonPrimitive (
242246 """
243247 query {
@@ -265,7 +269,6 @@ class UnitTestReport(private val apiToken: String) {
265269 """
266270 ),
267271 )
268- )
269272 )
270273 }
271274
@@ -281,14 +284,14 @@ class UnitTestReport(private val apiToken: String) {
281284 * Abstracts away paginated calling. Naively joins pages together by merging root level arrays.
282285 */
283286 private fun <T > request (uri : URI , clazz : Class <T >, payload : JsonObject ? = null): T {
284- val builder = HttpRequest .newBuilder()
285- if (payload == null ) {
286- builder.GET ()
287- } else {
288- builder.POST (HttpRequest .BodyPublishers .ofString(payload.toString()))
289- }
290287 val request =
291- builder
288+ HttpRequest .newBuilder().apply {
289+ if (payload == null ) {
290+ GET ()
291+ } else {
292+ POST (HttpRequest .BodyPublishers .ofString(payload.toString()))
293+ }
294+ }
292295 .uri(uri)
293296 .header(" Authorization" , " Bearer $apiToken " )
294297 .header(" X-GitHub-Api-Version" , " 2022-11-28" )
@@ -297,31 +300,31 @@ class UnitTestReport(private val apiToken: String) {
297300 val response = client.send(request, HttpResponse .BodyHandlers .ofString())
298301 val body = response.body()
299302 if (response.statusCode() >= 300 ) {
300- System .err. println (response)
301- System .err. println (body)
303+ LOG .error (response.toString() )
304+ LOG .error (body)
302305 }
303306 val json =
304307 when (clazz) {
305308 JsonObject ::class .java -> Json .decodeFromString<JsonObject >(body)
306309 JsonArray ::class .java -> Json .decodeFromString<JsonArray >(body)
307- else -> throw IllegalArgumentException ()
310+ else -> throw IllegalArgumentException (" Unsupported deserialization type of $clazz " )
308311 }
309312 if (json is JsonObject ) {
310313 // Retrieve and merge objects from other pages, if present
311314 return response
312315 .headers()
313316 .firstValue(" Link" )
314317 .map { link: String ->
315- val parts = link.split(" ," .toRegex() ).dropLastWhile { it.isEmpty() }
318+ val parts = link.split(" ," ).dropLastWhile { it.isEmpty() }
316319 for (part in parts) {
317320 if (part.endsWith(" rel=\" next\" " )) {
318321 // <foo>; rel="next" -> foo
319322 val url =
320323 part
321- .split(" >;" .toRegex() )
324+ .split(" >;" )
322325 .dropLastWhile { it.isEmpty() }
323326 .toTypedArray()[0 ]
324- .split(" <" .toRegex() )
327+ .split(" <" )
325328 .dropLastWhile { it.isEmpty() }
326329 .toTypedArray()[1 ]
327330 val p = request<JsonObject >(URI .create(url), JsonObject ::class .java)
0 commit comments