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

Commit f012c6f0 authored by Lee Shombert's avatar Lee Shombert Committed by Android (Google) Code Review
Browse files

Merge "Add a cache dumpsys test" into main

parents 4f0ebcb8 a1d9e10d
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -54,7 +54,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
@@ -2394,9 +2393,11 @@ public class PropertyInvalidatedCache<Query, Result> {
     * provided {@link PrintWriter}.  Optional switches allow the caller to choose
     * specific caches (selection is by cache name or property name); if these switches
     * are used then the output includes both cache statistics and cache entries.
     * @hide
     */
    @VisibleForTesting
    @NeverCompile
    private static void dumpCacheInfo(@NonNull PrintWriter pw, @NonNull String[] args) {
    public static void dumpCacheInfo(@NonNull PrintWriter pw, @NonNull String[] args) {
        if (!sEnabled) {
            pw.println("  Caching is disabled in this process.");
            return;
+1 −17
Original line number Diff line number Diff line
@@ -24,26 +24,10 @@ import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.app.PropertyInvalidatedCache;
import android.app.PropertyInvalidatedCache.Args;
import android.text.TextUtils;
import android.util.ArraySet;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.FastPrintWriter;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Random;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.concurrent.atomic.AtomicLong;

/**
 * LRU cache that's invalidated when an opaque value in a property changes. Self-synchronizing,
@@ -411,7 +395,7 @@ public class IpcDataCache<Query, Result> extends PropertyInvalidatedCache<Query,
     * 1. Instance-per-cache: create a static instance of this class using the same
     *    parameters as would have been given to IpcDataCache (or
     *    PropertyInvalidatedCache).  This static instance provides a hook for the
     *    invalidateCache() and disableForLocalProcess() calls, which, generally, must
     *    invalidateCache() and disableForCurrentProcess() calls, which, generally, must
     *    also be static.
     *
     * 2. Short-hand for shared configuration parameters: create an instance of this class
+79 −5
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@ import static android.app.PropertyInvalidatedCache.MODULE_SYSTEM;
import static android.app.PropertyInvalidatedCache.MODULE_TEST;
import static android.app.PropertyInvalidatedCache.NonceStore.INVALID_NONCE_INDEX;

import static com.google.common.truth.Truth.assertThat;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
@@ -33,17 +35,13 @@ import static org.junit.Assert.fail;

import android.annotation.SuppressLint;
import android.app.PropertyInvalidatedCache.Args;
import android.app.PropertyInvalidatedCache.NonceWatcher;
import android.app.PropertyInvalidatedCache.NonceStore;
import android.app.PropertyInvalidatedCache.NonceWatcher;
import android.os.Binder;
import android.util.Log;
import com.android.internal.os.ApplicationSharedMemory;

import android.platform.test.annotations.DisabledOnRavenwood;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.platform.test.ravenwood.RavenwoodRule;

import androidx.test.filters.SmallTest;

@@ -54,6 +52,8 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;

import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
import java.util.concurrent.TimeUnit;

/**
@@ -800,4 +800,78 @@ public class PropertyInvalidatedCacheTests {
        // The recompute is 4 because nulls were not cached.
        assertEquals(4, cache.getRecomputeCount());
    }

    // Collect the dumpsys output.  The boolean is for brief output.
    private static String getDumpsys(boolean brief) {
        final String[] args;
        if (brief) {
            args = new String[] { "-brief" };
        } else {
            args = new String[0];
        }

        ByteArrayOutputStream barray = new ByteArrayOutputStream();
        PrintWriter bout = new PrintWriter(barray);
        PropertyInvalidatedCache.dumpCacheInfo(bout, args);
        bout.close();
        return barray.toString();
    }

    @Test
    public void testDumpsysCacheinfo() {
        // Construct one well-known cache.
        TestCache cache = new TestCache(new Args(MODULE_TEST)
                .maxEntries(4).api("testDumpsys").cacheNulls(true),
                new TestQuery());
        cache.invalidateCache();

        String dump = getDumpsys(/* brief */ false);
        String p;

        // Test of the test.  If this test fails, it is likely that the dumpsys is badly broken.
        p = "Cache-key:";
        assertThat(dump).containsMatch(p);

        // Test of the test: this should fail.  This is not a functional test: if this test passes
        // then the logic in this test routine is faulty.
        p = "Cache-key: +notACache\\R +invalidated:1";
        assertThat(dump).doesNotContainMatch(p);

        // Verify that there is a handler for test/testDumpsys and it has one invalidation.
        p = "Cache-key: +test/testDumpsys\\R +invalidated:1";
        assertThat(dump).containsMatch(p);

        // Verify that the testDumpsys cache is present.  It has zero hits, misses, and clears.
        p = "Cache Name: testDumpsys\\R +Key: test/testDumpsys\\R"
            + " +Hits: 0, Misses: 0, Skips: 0";
        assertThat(dump).containsMatch(p);

        // Verify that the well-known cache getApplicationInfo is present.
        p = "Cache Name: getApplicationInfo";
        assertThat(dump).containsMatch(p);

        // Construct a brief listing.
        dump = getDumpsys(/* brief */ true);

        // Verify that there is a handler for test/testDumpsys and it has one invalidation.
        p = "Cache-key: +test/testDumpsys\\R +invalidated:1";
        assertThat(dump).containsMatch(p);

        // Verify that the testDumpsys cache is present.  It has zero hits, misses, and clears.
        p = "Cache Name: testDumpsys";
        assertThat(dump).doesNotContainMatch(p);

        // Add some activity.  Two misses and one hit.
        cache.query(1);
        cache.query(2);
        cache.query(1);

        // Construct a brief listing.
        dump = getDumpsys(/* brief */ true);

        // Verify that testDumpsys cache is present and it has the expected attributes.
        p = "Cache Name: testDumpsys\\R +Key: test/testDumpsys\\R"
            + " +Hits: 1, Misses: 2, Skips: 0";
        assertThat(dump).containsMatch(p);
    }
}