1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.server.am;
17 
18 import static com.google.common.truth.Truth.assertThat;
19 
20 import static org.junit.Assert.assertTrue;
21 
22 import androidx.test.filters.SmallTest;
23 
24 import org.junit.Test;
25 
26 @SmallTest
27 public class ActivityManagerUtilsTest {
28     @Test
getAndroidIdHash()29     public void getAndroidIdHash() {
30         // getAndroidIdHash() essentially returns a random a value. Just make sure it's
31         // non-negative.
32         assertThat(ActivityManagerUtils.getAndroidIdHash()).isAtLeast(0);
33     }
34 
35     @Test
getUnsignedHashCached()36     public void getUnsignedHashCached() {
37         assertThat(ActivityManagerUtils.getUnsignedHashCached("x")).isEqualTo(
38                 ActivityManagerUtils.getUnsignedHashCached("x"));
39 
40         assertThat(ActivityManagerUtils.getUnsignedHashCached("x")).isNotEqualTo(
41                 ActivityManagerUtils.getUnsignedHashCached("y"));
42     }
43 
44     @Test
shouldSamplePackage_sampleNone()45     public void shouldSamplePackage_sampleNone() {
46         final int numTests = 100000;
47         for (int i = 0; i < numTests; i++) {
48             assertThat(ActivityManagerUtils.shouldSamplePackageForAtom("" + i, 0))
49                     .isFalse();
50         }
51     }
52 
53     @Test
shouldSamplePackage_sampleAll()54     public void shouldSamplePackage_sampleAll() {
55         final int numTests = 100000;
56 
57         for (int i = 0; i < numTests; i++) {
58             assertThat(ActivityManagerUtils.shouldSamplePackageForAtom("" + i, 1))
59                     .isTrue();
60         }
61     }
62 
63     /**
64      * Make sure, with the same android ID, an expected rate of the packages are selected.
65      */
66     @Test
shouldSamplePackage_sampleSome_fixedAndroidId()67     public void shouldSamplePackage_sampleSome_fixedAndroidId() {
68         checkShouldSamplePackage_fixedAndroidId(0.1f);
69         checkShouldSamplePackage_fixedAndroidId(0.5f);
70         checkShouldSamplePackage_fixedAndroidId(0.9f);
71     }
72 
73     /**
74      * Make sure, the same package is selected on an expected rate of the devices.
75      */
76     @Test
shouldSamplePackage_sampleSome_fixedPackage()77     public void shouldSamplePackage_sampleSome_fixedPackage() {
78         checkShouldSamplePackage_fixedPackage(0.1f);
79         checkShouldSamplePackage_fixedPackage(0.5f);
80         checkShouldSamplePackage_fixedPackage(0.9f);
81     }
82 
checkShouldSamplePackage_fixedPackage(float sampleRate)83     private void checkShouldSamplePackage_fixedPackage(float sampleRate) {
84         checkShouldSamplePackage(sampleRate, sampleRate, true, false);
85     }
86 
checkShouldSamplePackage_fixedAndroidId(float sampleRate)87     private void checkShouldSamplePackage_fixedAndroidId(float sampleRate) {
88         checkShouldSamplePackage(sampleRate, sampleRate, false, true);
89     }
90 
91     @Test
testCheckShouldSamplePackage()92     public void testCheckShouldSamplePackage() {
93         // Just make sure checkShouldSamplePackage is actually working...
94         assertFailure(() -> checkShouldSamplePackage(0.3f, 0.6f, false, true));
95         assertFailure(() -> checkShouldSamplePackage(0.6f, 0.3f, true, false));
96     }
97 
assertFailure(Runnable r)98     private static void assertFailure(Runnable r) {
99         boolean failed = false;
100         try {
101             r.run();
102         } catch (AssertionError e) {
103             failed = true;
104         }
105         assertTrue(failed);
106     }
107 
checkShouldSamplePackage(float inputSampleRate, float expectedRate, boolean fixedPackage, boolean fixedAndroidId)108     private void checkShouldSamplePackage(float inputSampleRate, float expectedRate,
109             boolean fixedPackage, boolean fixedAndroidId) {
110         final int numTests = 100000;
111 
112         try {
113             int numSampled = 0;
114             for (int i = 0; i < numTests; i++) {
115                 final String pkg = fixedPackage ? "fixed-package" : "" + i;
116                 ActivityManagerUtils.injectAndroidIdForTest(
117                         fixedAndroidId ? "fixed-android-id" : "" + i);
118 
119                 if (ActivityManagerUtils.shouldSamplePackageForAtom(pkg, inputSampleRate)) {
120                     numSampled++;
121                 }
122                 assertThat(ActivityManagerUtils.getUnsignedHashCached(pkg)).isEqualTo(
123                         ActivityManagerUtils.getUnsignedHashCached(pkg));
124             }
125             final double actualSampleRate = ((double) numSampled) / numTests;
126 
127             assertThat(actualSampleRate).isWithin(0.05).of(expectedRate);
128         } finally {
129             ActivityManagerUtils.injectAndroidIdForTest(null);
130         }
131     }
132 }
133