Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a28b2a71 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Dump threads for troubleshooting when catalyst test timeout" into main

parents d10c7b32 54a36368
Loading
Loading
Loading
Loading
+30 −2
Original line number Original line Diff line number Diff line
@@ -27,6 +27,7 @@ import androidx.preference.PreferenceScreen
import androidx.test.core.app.ApplicationProvider
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertThat
import java.util.concurrent.atomic.AtomicBoolean
import org.junit.Rule
import org.junit.Rule
import org.junit.Test
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runner.RunWith
@@ -53,7 +54,7 @@ abstract class CatalystScreenTestCase {
        enableCatalystScreen()
        enableCatalystScreen()
        assertThat(preferenceScreenCreator.isFlagEnabled(context)).isTrue()
        assertThat(preferenceScreenCreator.isFlagEnabled(context)).isTrue()
        val catalystScreen = dumpPreferenceScreen()
        val catalystScreen = dumpPreferenceScreen()
        Log.i("Catalyst", catalystScreen)
        Log.i(TAG, catalystScreen)


        disableCatalystScreen()
        disableCatalystScreen()
        assertThat(preferenceScreenCreator.isFlagEnabled(context)).isFalse()
        assertThat(preferenceScreenCreator.isFlagEnabled(context)).isFalse()
@@ -83,11 +84,26 @@ abstract class CatalystScreenTestCase {
    }
    }


    private fun dumpPreferenceScreen(): String {
    private fun dumpPreferenceScreen(): String {
        // Dump threads for troubleshooting when the test thread is stuck.
        // Latest junit Timeout rule supports similar feature but it is not yet available on AOSP.
        val taskFinished = AtomicBoolean()
        Thread {
                Thread.sleep(20000)
                if (!taskFinished.get()) dumpThreads()
            }
            .apply {
                isDaemon = true
                start()
            }

        @Suppress("UNCHECKED_CAST")
        @Suppress("UNCHECKED_CAST")
        val clazz = preferenceScreenCreator.fragmentClass() as Class<PreferenceFragmentCompat>
        val clazz = preferenceScreenCreator.fragmentClass() as Class<PreferenceFragmentCompat>
        val builder = StringBuilder()
        val builder = StringBuilder()
        FragmentScenario.launch(clazz).use {
        FragmentScenario.launch(clazz).use {
            it.onFragment { fragment -> fragment.preferenceScreen.toString(builder) }
            it.onFragment { fragment ->
                taskFinished.set(true)
                fragment.preferenceScreen.toString(builder)
            }
        }
        }
        return builder.toString()
        return builder.toString()
    }
    }
@@ -120,4 +136,16 @@ abstract class CatalystScreenTestCase {
        }
        }
        builder.append(indent).append("}\n")
        builder.append(indent).append("}\n")
    }
    }

    companion object {
        const val TAG = "CatalystScreenTestCase"

        fun dumpThreads() {
            for ((thread, stack) in Thread.getAllStackTraces()) {
                Log.i(TAG, "$thread")
                for (frame in stack) Log.i(TAG, "  $frame")
                Log.i(TAG, "")
            }
        }
    }
}
}