/* * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.log.echo import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.log.core.LogLevel.DEBUG import com.android.systemui.log.core.LogLevel.ERROR import com.android.systemui.log.core.LogLevel.INFO import com.android.systemui.log.core.LogLevel.VERBOSE import com.android.systemui.log.core.LogLevel.WARNING import com.android.systemui.log.echo.EchoOverrideType.BUFFER import com.android.systemui.log.echo.EchoOverrideType.TAG import com.android.systemui.statusbar.commandline.CommandRegistry import com.android.systemui.util.settings.FakeGlobalSettings import kotlin.test.assertEquals import kotlin.test.assertNotNull import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.StandardTestDispatcher import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.advanceUntilIdle import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Test import org.mockito.Mock import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest class LogcatEchoTrackerDebugTest : SysuiTestCase() { private val dispatcher = StandardTestDispatcher() private val testScope = TestScope(dispatcher) private val globalSettings = FakeGlobalSettings() @Mock private lateinit var commandRegistry: CommandRegistry private lateinit var echoTracker: LogcatEchoTrackerDebug @Before fun setup() { MockitoAnnotations.initMocks(this) echoTracker = LogcatEchoTrackerDebug( testScope, dispatcher, globalSettings, commandRegistry, ) } @Test fun testUnsetLogLevelIsWarning() { assertTrue(echoTracker.isBufferLoggable("foo", WARNING)) assertFalse(echoTracker.isBufferLoggable("foo", INFO)) assertTrue(echoTracker.isTagLoggable("foo", WARNING)) assertFalse(echoTracker.isTagLoggable("foo", INFO)) } @Test fun testLoadEmptySetting() = testScope.runTest { startAndLoadOverrides() assertFalse(echoTracker.isBufferLoggable("foo", INFO)) assertFalse(echoTracker.isTagLoggable("foo", INFO)) } @Test fun testLoadOverridesFromSettings() = testScope.runTest { setOverrides( LogcatEchoOverride(BUFFER, "buffer_1", DEBUG), LogcatEchoOverride(TAG, "tag_1", INFO), ) startAndLoadOverrides() assertTrue(echoTracker.isBufferLoggable("buffer_1", DEBUG)) assertFalse(echoTracker.isBufferLoggable("buffer_1", VERBOSE)) assertTrue(echoTracker.isTagLoggable("tag_1", INFO)) assertFalse(echoTracker.isTagLoggable("tag_1", DEBUG)) } @Test fun testSetOverride() = testScope.runTest { setOverrides( LogcatEchoOverride(BUFFER, "buffer_0", VERBOSE), ) startAndLoadOverrides() echoTracker.setEchoLevel(BUFFER, "buffer_1", DEBUG) echoTracker.setEchoLevel(TAG, "tag_1", ERROR) advanceUntilIdle() assertTrue(echoTracker.isBufferLoggable("buffer_0", VERBOSE)) assertTrue(echoTracker.isBufferLoggable("buffer_1", DEBUG)) assertFalse(echoTracker.isBufferLoggable("buffer_1", VERBOSE)) assertTrue(echoTracker.isTagLoggable("tag_1", ERROR)) assertFalse(echoTracker.isTagLoggable("tag_1", WARNING)) } @Test fun testSetOverrideNotAppliedUntilCoroutinesRun() = testScope.runTest { startAndLoadOverrides() echoTracker.setEchoLevel(BUFFER, "buffer_1", DEBUG) assertTrue(echoTracker.isBufferLoggable("buffer_1", WARNING)) assertFalse(echoTracker.isBufferLoggable("buffer_1", INFO)) } @Test fun testSetOverrideStoresInSettings() = testScope.runTest { setOverrides( LogcatEchoOverride(BUFFER, "buffer_1", DEBUG), ) startAndLoadOverrides() echoTracker.setEchoLevel(BUFFER, "buffer_2", INFO) echoTracker.setEchoLevel(TAG, "tag_1", ERROR) advanceUntilIdle() val expected = setOf( LogcatEchoOverride(BUFFER, "buffer_1", DEBUG), LogcatEchoOverride(BUFFER, "buffer_2", INFO), LogcatEchoOverride(TAG, "tag_1", ERROR), ) assertEquals(expected, loadStoredOverrideSet()) } @Test fun testClearAllOverrides() = testScope.runTest { setOverrides( LogcatEchoOverride(BUFFER, "buffer_1", DEBUG), LogcatEchoOverride(TAG, "tag_1", INFO), ) startAndLoadOverrides() echoTracker.setEchoLevel(BUFFER, "buffer_2", VERBOSE) advanceUntilIdle() echoTracker.clearAllOverrides() runCurrent() assertFalse(echoTracker.isBufferLoggable("buffer_1", DEBUG)) assertFalse(echoTracker.isTagLoggable("tag_1", INFO)) assertFalse(echoTracker.isBufferLoggable("buffer_2", VERBOSE)) advanceUntilIdle() assertEquals(emptySet(), loadStoredOverrideSet()) } private fun setOverrides(vararg overrides: LogcatEchoOverride) { val encoded = LogcatEchoSettingFormat().stringifyOverrides(overrides.asList()) globalSettings.putString(OVERRIDE_SETTING_PATH, encoded) echoTracker.start() } private fun loadStoredOverrideSet(): Set { val storedSetting = assertNotNull(globalSettings.getString(OVERRIDE_SETTING_PATH)) return LogcatEchoSettingFormat().parseOverrides(storedSetting).toSet() } private fun TestScope.startAndLoadOverrides() { echoTracker.start() advanceUntilIdle() } companion object { private const val OVERRIDE_SETTING_PATH = "systemui/logbuffer_echo_overrides" } }