Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java +81 −112 Original line number Diff line number Diff line Loading @@ -48,7 +48,6 @@ import android.os.SystemClock; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.util.ArrayMap; import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; Loading @@ -56,6 +55,7 @@ import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.dump.DumpManager; import com.android.systemui.log.LogAssertKt; import com.android.systemui.statusbar.NotificationInteractionTracker; import com.android.systemui.statusbar.RankingBuilder; import com.android.systemui.statusbar.notification.NotifPipelineFlags; Loading @@ -76,6 +76,7 @@ import com.android.systemui.statusbar.notification.collection.listbuilder.plugga import com.android.systemui.statusbar.notification.collection.notifcollection.CollectionReadyForBuildListener; import com.android.systemui.util.time.FakeSystemClock; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; Loading Loading @@ -129,10 +130,6 @@ public class ShadeListBuilderTest extends SysuiTestCase { private Map<String, Integer> mNextIdMap = new ArrayMap<>(); private int mNextRank = 0; private Log.TerribleFailureHandler mOldWtfHandler = null; private Log.TerribleFailure mLastWtf = null; private int mWtfCount = 0; @Before public void setUp() { MockitoAnnotations.initMocks(this); Loading Loading @@ -1756,20 +1753,19 @@ public class ShadeListBuilderTest extends SysuiTestCase { mListBuilder.addPreGroupFilter(filter); mListBuilder.addOnBeforeTransformGroupsListener(listener); interceptWtfs(); // WHEN we try to run the pipeline and the filter is invalidated exactly // MAX_CONSECUTIVE_REENTRANT_REBUILDS times, addNotif(0, PACKAGE_2); invalidator.setInvalidationCount(MAX_CONSECUTIVE_REENTRANT_REBUILDS); dispatchBuild(); runWhileScheduledUpTo(MAX_CONSECUTIVE_REENTRANT_REBUILDS + 2); // THEN an exception is NOT thrown directly, but a WTF IS logged. expectWtfs(MAX_CONSECUTIVE_REENTRANT_REBUILDS); LogAssertKt.assertLogsWtfs(() -> { dispatchBuild(); runWhileScheduledUpTo(MAX_CONSECUTIVE_REENTRANT_REBUILDS + 2); }); } @Test(expected = IllegalStateException.class) @Test public void testOutOfOrderPreGroupFilterInvalidationThrowsAfterTooManyRuns() { // GIVEN a PreGroupNotifFilter that gets invalidated during the grouping stage, NotifFilter filter = new PackageFilter(PACKAGE_1); Loading @@ -1778,20 +1774,20 @@ public class ShadeListBuilderTest extends SysuiTestCase { mListBuilder.addPreGroupFilter(filter); mListBuilder.addOnBeforeTransformGroupsListener(listener); interceptWtfs(); // WHEN we try to run the pipeline and the filter is invalidated more than // MAX_CONSECUTIVE_REENTRANT_REBUILDS times, // THEN an exception IS thrown. addNotif(0, PACKAGE_2); invalidator.setInvalidationCount(MAX_CONSECUTIVE_REENTRANT_REBUILDS + 1); LogAssertKt.assertLogsWtfs(() -> { Assert.assertThrows(IllegalStateException.class, () -> { dispatchBuild(); try { runWhileScheduledUpTo(MAX_CONSECUTIVE_REENTRANT_REBUILDS + 2); } finally { expectWtfs(MAX_CONSECUTIVE_REENTRANT_REBUILDS); } // THEN an exception IS thrown. }); }); } @Test Loading @@ -1803,26 +1799,30 @@ public class ShadeListBuilderTest extends SysuiTestCase { mListBuilder.addPreGroupFilter(filter); mListBuilder.addOnBeforeTransformGroupsListener(listener); interceptWtfs(); // WHEN we try to run the pipeline and the filter is invalidated // MAX_CONSECUTIVE_REENTRANT_REBUILDS times, the pipeline runs for a non-reentrant reason, // and then the filter is invalidated MAX_CONSECUTIVE_REENTRANT_REBUILDS times again, // THEN an exception is NOT thrown, but WTFs ARE logged. addNotif(0, PACKAGE_2); invalidator.setInvalidationCount(MAX_CONSECUTIVE_REENTRANT_REBUILDS); LogAssertKt.assertLogsWtfs(() -> { dispatchBuild(); runWhileScheduledUpTo(MAX_CONSECUTIVE_REENTRANT_REBUILDS + 2); }); invalidator.setInvalidationCount(MAX_CONSECUTIVE_REENTRANT_REBUILDS); LogAssertKt.assertLogsWtfs(() -> { // Note: dispatchBuild itself triggers a non-reentrant pipeline run. dispatchBuild(); runWhileScheduledUpTo(MAX_CONSECUTIVE_REENTRANT_REBUILDS + 2); // THEN an exception is NOT thrown, but WTFs ARE logged. expectWtfs(MAX_CONSECUTIVE_REENTRANT_REBUILDS * 2); }); } @Test public void testOutOfOrderPrompterInvalidationDoesNotThrowBeforeTooManyRuns() { public void testOutOfOrderPromoterInvalidationDoesNotThrowBeforeTooManyRuns() { // GIVEN a NotifPromoter that gets invalidated during the sorting stage, NotifPromoter promoter = new IdPromoter(47); CountingInvalidator invalidator = new CountingInvalidator(promoter); Loading @@ -1830,22 +1830,22 @@ public class ShadeListBuilderTest extends SysuiTestCase { mListBuilder.addPromoter(promoter); mListBuilder.addOnBeforeSortListener(listener); interceptWtfs(); // WHEN we try to run the pipeline and the promoter is invalidated exactly // MAX_CONSECUTIVE_REENTRANT_REBUILDS times, // THEN an exception is NOT thrown directly, but a WTF IS logged. addNotif(0, PACKAGE_1); invalidator.setInvalidationCount(MAX_CONSECUTIVE_REENTRANT_REBUILDS); LogAssertKt.assertLogsWtfs(() -> { dispatchBuild(); runWhileScheduledUpTo(MAX_CONSECUTIVE_REENTRANT_REBUILDS + 2); // THEN an exception is NOT thrown directly, but a WTF IS logged. expectWtfs(MAX_CONSECUTIVE_REENTRANT_REBUILDS); }); } @Test(expected = IllegalStateException.class) public void testOutOfOrderPrompterInvalidationThrowsAfterTooManyRuns() { @Test public void testOutOfOrderPromoterInvalidationThrowsAfterTooManyRuns() { // GIVEN a NotifPromoter that gets invalidated during the sorting stage, NotifPromoter promoter = new IdPromoter(47); CountingInvalidator invalidator = new CountingInvalidator(promoter); Loading @@ -1853,20 +1853,20 @@ public class ShadeListBuilderTest extends SysuiTestCase { mListBuilder.addPromoter(promoter); mListBuilder.addOnBeforeSortListener(listener); interceptWtfs(); // WHEN we try to run the pipeline and the promoter is invalidated more than // MAX_CONSECUTIVE_REENTRANT_REBUILDS times, // THEN an exception IS thrown. addNotif(0, PACKAGE_1); invalidator.setInvalidationCount(MAX_CONSECUTIVE_REENTRANT_REBUILDS + 1); LogAssertKt.assertLogsWtfs(() -> { Assert.assertThrows(IllegalStateException.class, () -> { dispatchBuild(); try { runWhileScheduledUpTo(MAX_CONSECUTIVE_REENTRANT_REBUILDS + 2); } finally { expectWtfs(MAX_CONSECUTIVE_REENTRANT_REBUILDS); } // THEN an exception IS thrown. }); }); } @Test Loading @@ -1878,20 +1878,21 @@ public class ShadeListBuilderTest extends SysuiTestCase { mListBuilder.setComparators(singletonList(comparator)); mListBuilder.addOnBeforeRenderListListener(listener); interceptWtfs(); // WHEN we try to run the pipeline and the comparator is invalidated exactly // MAX_CONSECUTIVE_REENTRANT_REBUILDS times, // THEN an exception is NOT thrown directly, but a WTF IS logged. addNotif(0, PACKAGE_2); invalidator.setInvalidationCount(MAX_CONSECUTIVE_REENTRANT_REBUILDS); LogAssertKt.assertLogsWtfs(() -> { dispatchBuild(); runWhileScheduledUpTo(MAX_CONSECUTIVE_REENTRANT_REBUILDS + 2); // THEN an exception is NOT thrown directly, but a WTF IS logged. expectWtfs(MAX_CONSECUTIVE_REENTRANT_REBUILDS); }); } @Test(expected = IllegalStateException.class) @Test public void testOutOfOrderComparatorInvalidationThrowsAfterTooManyRuns() { // GIVEN a NotifComparator that gets invalidated during the finalizing stage, NotifComparator comparator = new HypeComparator(PACKAGE_1); Loading @@ -1900,16 +1901,20 @@ public class ShadeListBuilderTest extends SysuiTestCase { mListBuilder.setComparators(singletonList(comparator)); mListBuilder.addOnBeforeRenderListListener(listener); interceptWtfs(); // WHEN we try to run the pipeline and the comparator is invalidated more than // MAX_CONSECUTIVE_REENTRANT_REBUILDS times, // THEN an exception IS thrown. addNotif(0, PACKAGE_2); invalidator.setInvalidationCount(MAX_CONSECUTIVE_REENTRANT_REBUILDS + 1); LogAssertKt.assertLogsWtfs(() -> { Assert.assertThrows(IllegalStateException.class, () -> { dispatchBuild(); runWhileScheduledUpTo(MAX_CONSECUTIVE_REENTRANT_REBUILDS + 2); // THEN an exception IS thrown. }); }); } @Test Loading @@ -1921,20 +1926,21 @@ public class ShadeListBuilderTest extends SysuiTestCase { mListBuilder.addFinalizeFilter(filter); mListBuilder.addOnBeforeRenderListListener(listener); interceptWtfs(); // WHEN we try to run the pipeline and the PreRenderFilter is invalidated exactly // MAX_CONSECUTIVE_REENTRANT_REBUILDS times, // THEN an exception is NOT thrown directly, but a WTF IS logged. addNotif(0, PACKAGE_2); invalidator.setInvalidationCount(MAX_CONSECUTIVE_REENTRANT_REBUILDS); LogAssertKt.assertLogsWtfs(() -> { dispatchBuild(); runWhileScheduledUpTo(MAX_CONSECUTIVE_REENTRANT_REBUILDS + 2); // THEN an exception is NOT thrown directly, but a WTF IS logged. expectWtfs(MAX_CONSECUTIVE_REENTRANT_REBUILDS); }); } @Test(expected = IllegalStateException.class) @Test public void testOutOfOrderPreRenderFilterInvalidationThrowsAfterTooManyRuns() { // GIVEN a PreRenderNotifFilter that gets invalidated during the finalizing stage, NotifFilter filter = new PackageFilter(PACKAGE_1); Loading @@ -1943,57 +1949,20 @@ public class ShadeListBuilderTest extends SysuiTestCase { mListBuilder.addFinalizeFilter(filter); mListBuilder.addOnBeforeRenderListListener(listener); interceptWtfs(); // WHEN we try to run the pipeline and the PreRenderFilter is invalidated more than // MAX_CONSECUTIVE_REENTRANT_REBUILDS times, addNotif(0, PACKAGE_2); invalidator.setInvalidationCount(MAX_CONSECUTIVE_REENTRANT_REBUILDS + 1); dispatchBuild(); try { runWhileScheduledUpTo(MAX_CONSECUTIVE_REENTRANT_REBUILDS + 2); } finally { expectWtfs(MAX_CONSECUTIVE_REENTRANT_REBUILDS); } // THEN an exception IS thrown. } private void interceptWtfs() { assertNull(mOldWtfHandler); mLastWtf = null; mWtfCount = 0; addNotif(0, PACKAGE_2); invalidator.setInvalidationCount(MAX_CONSECUTIVE_REENTRANT_REBUILDS + 1); mOldWtfHandler = Log.setWtfHandler((tag, e, system) -> { Log.e("ShadeListBuilderTest", "Observed WTF: " + e); mLastWtf = e; mWtfCount++; LogAssertKt.assertLogsWtfs(() -> { Assert.assertThrows(IllegalStateException.class, () -> { dispatchBuild(); runWhileScheduledUpTo(MAX_CONSECUTIVE_REENTRANT_REBUILDS + 2); }); }); } private void expectNoWtfs() { assertNull(expectWtfs(0)); } private Log.TerribleFailure expectWtf() { return expectWtfs(1); } private Log.TerribleFailure expectWtfs(int expectedWtfCount) { assertNotNull(mOldWtfHandler); Log.setWtfHandler(mOldWtfHandler); mOldWtfHandler = null; Log.TerribleFailure wtf = mLastWtf; int wtfCount = mWtfCount; mLastWtf = null; mWtfCount = 0; assertEquals(expectedWtfCount, wtfCount); return wtf; } @Test Loading packages/SystemUI/tests/utils/src/com/android/systemui/log/LogAssert.kt +11 −0 Original line number Diff line number Diff line Loading @@ -59,6 +59,17 @@ fun assertLogsWtf( ): TerribleFailureLog = assertLogsWtf(message = message, allowMultiple = allowMultiple) { loggingRunnable.run() } fun assertLogsWtfs( message: String = "Expected Log.wtf to be called once or more", loggingBlock: () -> Unit, ): TerribleFailureLog = assertLogsWtf(message, allowMultiple = true, loggingBlock) @JvmOverloads fun assertLogsWtfs( message: String = "Expected Log.wtf to be called once or more", loggingRunnable: Runnable, ): TerribleFailureLog = assertLogsWtfs(message) { loggingRunnable.run() } /** The data passed to [TerribleFailureHandler.onTerribleFailure] */ data class TerribleFailureLog( val tag: String, Loading Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java +81 −112 Original line number Diff line number Diff line Loading @@ -48,7 +48,6 @@ import android.os.SystemClock; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.util.ArrayMap; import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; Loading @@ -56,6 +55,7 @@ import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.dump.DumpManager; import com.android.systemui.log.LogAssertKt; import com.android.systemui.statusbar.NotificationInteractionTracker; import com.android.systemui.statusbar.RankingBuilder; import com.android.systemui.statusbar.notification.NotifPipelineFlags; Loading @@ -76,6 +76,7 @@ import com.android.systemui.statusbar.notification.collection.listbuilder.plugga import com.android.systemui.statusbar.notification.collection.notifcollection.CollectionReadyForBuildListener; import com.android.systemui.util.time.FakeSystemClock; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; Loading Loading @@ -129,10 +130,6 @@ public class ShadeListBuilderTest extends SysuiTestCase { private Map<String, Integer> mNextIdMap = new ArrayMap<>(); private int mNextRank = 0; private Log.TerribleFailureHandler mOldWtfHandler = null; private Log.TerribleFailure mLastWtf = null; private int mWtfCount = 0; @Before public void setUp() { MockitoAnnotations.initMocks(this); Loading Loading @@ -1756,20 +1753,19 @@ public class ShadeListBuilderTest extends SysuiTestCase { mListBuilder.addPreGroupFilter(filter); mListBuilder.addOnBeforeTransformGroupsListener(listener); interceptWtfs(); // WHEN we try to run the pipeline and the filter is invalidated exactly // MAX_CONSECUTIVE_REENTRANT_REBUILDS times, addNotif(0, PACKAGE_2); invalidator.setInvalidationCount(MAX_CONSECUTIVE_REENTRANT_REBUILDS); dispatchBuild(); runWhileScheduledUpTo(MAX_CONSECUTIVE_REENTRANT_REBUILDS + 2); // THEN an exception is NOT thrown directly, but a WTF IS logged. expectWtfs(MAX_CONSECUTIVE_REENTRANT_REBUILDS); LogAssertKt.assertLogsWtfs(() -> { dispatchBuild(); runWhileScheduledUpTo(MAX_CONSECUTIVE_REENTRANT_REBUILDS + 2); }); } @Test(expected = IllegalStateException.class) @Test public void testOutOfOrderPreGroupFilterInvalidationThrowsAfterTooManyRuns() { // GIVEN a PreGroupNotifFilter that gets invalidated during the grouping stage, NotifFilter filter = new PackageFilter(PACKAGE_1); Loading @@ -1778,20 +1774,20 @@ public class ShadeListBuilderTest extends SysuiTestCase { mListBuilder.addPreGroupFilter(filter); mListBuilder.addOnBeforeTransformGroupsListener(listener); interceptWtfs(); // WHEN we try to run the pipeline and the filter is invalidated more than // MAX_CONSECUTIVE_REENTRANT_REBUILDS times, // THEN an exception IS thrown. addNotif(0, PACKAGE_2); invalidator.setInvalidationCount(MAX_CONSECUTIVE_REENTRANT_REBUILDS + 1); LogAssertKt.assertLogsWtfs(() -> { Assert.assertThrows(IllegalStateException.class, () -> { dispatchBuild(); try { runWhileScheduledUpTo(MAX_CONSECUTIVE_REENTRANT_REBUILDS + 2); } finally { expectWtfs(MAX_CONSECUTIVE_REENTRANT_REBUILDS); } // THEN an exception IS thrown. }); }); } @Test Loading @@ -1803,26 +1799,30 @@ public class ShadeListBuilderTest extends SysuiTestCase { mListBuilder.addPreGroupFilter(filter); mListBuilder.addOnBeforeTransformGroupsListener(listener); interceptWtfs(); // WHEN we try to run the pipeline and the filter is invalidated // MAX_CONSECUTIVE_REENTRANT_REBUILDS times, the pipeline runs for a non-reentrant reason, // and then the filter is invalidated MAX_CONSECUTIVE_REENTRANT_REBUILDS times again, // THEN an exception is NOT thrown, but WTFs ARE logged. addNotif(0, PACKAGE_2); invalidator.setInvalidationCount(MAX_CONSECUTIVE_REENTRANT_REBUILDS); LogAssertKt.assertLogsWtfs(() -> { dispatchBuild(); runWhileScheduledUpTo(MAX_CONSECUTIVE_REENTRANT_REBUILDS + 2); }); invalidator.setInvalidationCount(MAX_CONSECUTIVE_REENTRANT_REBUILDS); LogAssertKt.assertLogsWtfs(() -> { // Note: dispatchBuild itself triggers a non-reentrant pipeline run. dispatchBuild(); runWhileScheduledUpTo(MAX_CONSECUTIVE_REENTRANT_REBUILDS + 2); // THEN an exception is NOT thrown, but WTFs ARE logged. expectWtfs(MAX_CONSECUTIVE_REENTRANT_REBUILDS * 2); }); } @Test public void testOutOfOrderPrompterInvalidationDoesNotThrowBeforeTooManyRuns() { public void testOutOfOrderPromoterInvalidationDoesNotThrowBeforeTooManyRuns() { // GIVEN a NotifPromoter that gets invalidated during the sorting stage, NotifPromoter promoter = new IdPromoter(47); CountingInvalidator invalidator = new CountingInvalidator(promoter); Loading @@ -1830,22 +1830,22 @@ public class ShadeListBuilderTest extends SysuiTestCase { mListBuilder.addPromoter(promoter); mListBuilder.addOnBeforeSortListener(listener); interceptWtfs(); // WHEN we try to run the pipeline and the promoter is invalidated exactly // MAX_CONSECUTIVE_REENTRANT_REBUILDS times, // THEN an exception is NOT thrown directly, but a WTF IS logged. addNotif(0, PACKAGE_1); invalidator.setInvalidationCount(MAX_CONSECUTIVE_REENTRANT_REBUILDS); LogAssertKt.assertLogsWtfs(() -> { dispatchBuild(); runWhileScheduledUpTo(MAX_CONSECUTIVE_REENTRANT_REBUILDS + 2); // THEN an exception is NOT thrown directly, but a WTF IS logged. expectWtfs(MAX_CONSECUTIVE_REENTRANT_REBUILDS); }); } @Test(expected = IllegalStateException.class) public void testOutOfOrderPrompterInvalidationThrowsAfterTooManyRuns() { @Test public void testOutOfOrderPromoterInvalidationThrowsAfterTooManyRuns() { // GIVEN a NotifPromoter that gets invalidated during the sorting stage, NotifPromoter promoter = new IdPromoter(47); CountingInvalidator invalidator = new CountingInvalidator(promoter); Loading @@ -1853,20 +1853,20 @@ public class ShadeListBuilderTest extends SysuiTestCase { mListBuilder.addPromoter(promoter); mListBuilder.addOnBeforeSortListener(listener); interceptWtfs(); // WHEN we try to run the pipeline and the promoter is invalidated more than // MAX_CONSECUTIVE_REENTRANT_REBUILDS times, // THEN an exception IS thrown. addNotif(0, PACKAGE_1); invalidator.setInvalidationCount(MAX_CONSECUTIVE_REENTRANT_REBUILDS + 1); LogAssertKt.assertLogsWtfs(() -> { Assert.assertThrows(IllegalStateException.class, () -> { dispatchBuild(); try { runWhileScheduledUpTo(MAX_CONSECUTIVE_REENTRANT_REBUILDS + 2); } finally { expectWtfs(MAX_CONSECUTIVE_REENTRANT_REBUILDS); } // THEN an exception IS thrown. }); }); } @Test Loading @@ -1878,20 +1878,21 @@ public class ShadeListBuilderTest extends SysuiTestCase { mListBuilder.setComparators(singletonList(comparator)); mListBuilder.addOnBeforeRenderListListener(listener); interceptWtfs(); // WHEN we try to run the pipeline and the comparator is invalidated exactly // MAX_CONSECUTIVE_REENTRANT_REBUILDS times, // THEN an exception is NOT thrown directly, but a WTF IS logged. addNotif(0, PACKAGE_2); invalidator.setInvalidationCount(MAX_CONSECUTIVE_REENTRANT_REBUILDS); LogAssertKt.assertLogsWtfs(() -> { dispatchBuild(); runWhileScheduledUpTo(MAX_CONSECUTIVE_REENTRANT_REBUILDS + 2); // THEN an exception is NOT thrown directly, but a WTF IS logged. expectWtfs(MAX_CONSECUTIVE_REENTRANT_REBUILDS); }); } @Test(expected = IllegalStateException.class) @Test public void testOutOfOrderComparatorInvalidationThrowsAfterTooManyRuns() { // GIVEN a NotifComparator that gets invalidated during the finalizing stage, NotifComparator comparator = new HypeComparator(PACKAGE_1); Loading @@ -1900,16 +1901,20 @@ public class ShadeListBuilderTest extends SysuiTestCase { mListBuilder.setComparators(singletonList(comparator)); mListBuilder.addOnBeforeRenderListListener(listener); interceptWtfs(); // WHEN we try to run the pipeline and the comparator is invalidated more than // MAX_CONSECUTIVE_REENTRANT_REBUILDS times, // THEN an exception IS thrown. addNotif(0, PACKAGE_2); invalidator.setInvalidationCount(MAX_CONSECUTIVE_REENTRANT_REBUILDS + 1); LogAssertKt.assertLogsWtfs(() -> { Assert.assertThrows(IllegalStateException.class, () -> { dispatchBuild(); runWhileScheduledUpTo(MAX_CONSECUTIVE_REENTRANT_REBUILDS + 2); // THEN an exception IS thrown. }); }); } @Test Loading @@ -1921,20 +1926,21 @@ public class ShadeListBuilderTest extends SysuiTestCase { mListBuilder.addFinalizeFilter(filter); mListBuilder.addOnBeforeRenderListListener(listener); interceptWtfs(); // WHEN we try to run the pipeline and the PreRenderFilter is invalidated exactly // MAX_CONSECUTIVE_REENTRANT_REBUILDS times, // THEN an exception is NOT thrown directly, but a WTF IS logged. addNotif(0, PACKAGE_2); invalidator.setInvalidationCount(MAX_CONSECUTIVE_REENTRANT_REBUILDS); LogAssertKt.assertLogsWtfs(() -> { dispatchBuild(); runWhileScheduledUpTo(MAX_CONSECUTIVE_REENTRANT_REBUILDS + 2); // THEN an exception is NOT thrown directly, but a WTF IS logged. expectWtfs(MAX_CONSECUTIVE_REENTRANT_REBUILDS); }); } @Test(expected = IllegalStateException.class) @Test public void testOutOfOrderPreRenderFilterInvalidationThrowsAfterTooManyRuns() { // GIVEN a PreRenderNotifFilter that gets invalidated during the finalizing stage, NotifFilter filter = new PackageFilter(PACKAGE_1); Loading @@ -1943,57 +1949,20 @@ public class ShadeListBuilderTest extends SysuiTestCase { mListBuilder.addFinalizeFilter(filter); mListBuilder.addOnBeforeRenderListListener(listener); interceptWtfs(); // WHEN we try to run the pipeline and the PreRenderFilter is invalidated more than // MAX_CONSECUTIVE_REENTRANT_REBUILDS times, addNotif(0, PACKAGE_2); invalidator.setInvalidationCount(MAX_CONSECUTIVE_REENTRANT_REBUILDS + 1); dispatchBuild(); try { runWhileScheduledUpTo(MAX_CONSECUTIVE_REENTRANT_REBUILDS + 2); } finally { expectWtfs(MAX_CONSECUTIVE_REENTRANT_REBUILDS); } // THEN an exception IS thrown. } private void interceptWtfs() { assertNull(mOldWtfHandler); mLastWtf = null; mWtfCount = 0; addNotif(0, PACKAGE_2); invalidator.setInvalidationCount(MAX_CONSECUTIVE_REENTRANT_REBUILDS + 1); mOldWtfHandler = Log.setWtfHandler((tag, e, system) -> { Log.e("ShadeListBuilderTest", "Observed WTF: " + e); mLastWtf = e; mWtfCount++; LogAssertKt.assertLogsWtfs(() -> { Assert.assertThrows(IllegalStateException.class, () -> { dispatchBuild(); runWhileScheduledUpTo(MAX_CONSECUTIVE_REENTRANT_REBUILDS + 2); }); }); } private void expectNoWtfs() { assertNull(expectWtfs(0)); } private Log.TerribleFailure expectWtf() { return expectWtfs(1); } private Log.TerribleFailure expectWtfs(int expectedWtfCount) { assertNotNull(mOldWtfHandler); Log.setWtfHandler(mOldWtfHandler); mOldWtfHandler = null; Log.TerribleFailure wtf = mLastWtf; int wtfCount = mWtfCount; mLastWtf = null; mWtfCount = 0; assertEquals(expectedWtfCount, wtfCount); return wtf; } @Test Loading
packages/SystemUI/tests/utils/src/com/android/systemui/log/LogAssert.kt +11 −0 Original line number Diff line number Diff line Loading @@ -59,6 +59,17 @@ fun assertLogsWtf( ): TerribleFailureLog = assertLogsWtf(message = message, allowMultiple = allowMultiple) { loggingRunnable.run() } fun assertLogsWtfs( message: String = "Expected Log.wtf to be called once or more", loggingBlock: () -> Unit, ): TerribleFailureLog = assertLogsWtf(message, allowMultiple = true, loggingBlock) @JvmOverloads fun assertLogsWtfs( message: String = "Expected Log.wtf to be called once or more", loggingRunnable: Runnable, ): TerribleFailureLog = assertLogsWtfs(message) { loggingRunnable.run() } /** The data passed to [TerribleFailureHandler.onTerribleFailure] */ data class TerribleFailureLog( val tag: String, Loading