1 /* 2 * Copyright (C) 2023 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 17 package com.android.telephony.statslib; 18 19 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; 20 21 import static org.junit.Assert.assertEquals; 22 import static org.mockito.ArgumentMatchers.any; 23 import static org.mockito.Mockito.never; 24 import static org.mockito.Mockito.spy; 25 import static org.mockito.Mockito.timeout; 26 import static org.mockito.Mockito.times; 27 import static org.mockito.Mockito.verify; 28 import static org.mockito.Mockito.when; 29 30 import android.content.Context; 31 import android.util.StatsLog; 32 33 import androidx.test.core.app.ApplicationProvider; 34 35 import org.junit.After; 36 import org.junit.Before; 37 import org.junit.Test; 38 import org.junit.runner.RunWith; 39 import org.junit.runners.JUnit4; 40 import org.mockito.Mock; 41 import org.mockito.MockitoAnnotations; 42 import org.mockito.MockitoSession; 43 import org.mockito.quality.Strictness; 44 45 import java.util.Random; 46 import java.util.concurrent.Callable; 47 import java.util.concurrent.ExecutionException; 48 import java.util.concurrent.Executors; 49 import java.util.concurrent.ScheduledExecutorService; 50 import java.util.concurrent.ScheduledFuture; 51 import java.util.concurrent.TimeUnit; 52 53 @RunWith(JUnit4.class) 54 public class StatsLibTest { 55 56 private static final String RET_SUCCESS = "success"; 57 private static final String RET_FAILED = "failed"; 58 59 @Mock Context mMockContext; 60 @Mock StatsLibPulledAtomCallback mMockPulledAtomCallback; 61 @Mock StatsLibStorage mMockStorage; 62 @Mock PulledCallback mMockPulledCallback; 63 private StatsLib mStatsLib; 64 private MockitoSession mMockitoSession; 65 66 @Before setUp()67 public void setUp() { 68 MockitoAnnotations.initMocks(this); 69 mMockContext = spy(ApplicationProvider.getApplicationContext()); 70 mMockitoSession = 71 mockitoSession() 72 .strictness(Strictness.LENIENT) 73 .mockStatic(StatsLog.class) 74 .startMocking(); 75 when(mMockPulledAtomCallback.getStatsLibStorage()).thenReturn(mMockStorage); 76 mStatsLib = new StatsLib(mMockPulledAtomCallback); 77 } 78 79 @After tearDown()80 public void tearDown() { 81 mStatsLib = null; 82 if (mMockitoSession != null) { 83 mMockitoSession.finishMocking(); 84 mMockitoSession = null; 85 } 86 } 87 88 @Test testWritePushedAtomHandler()89 public void testWritePushedAtomHandler() { 90 AtomsPushedTestInfo first = new AtomsPushedTestInfo(1); 91 AtomsPushedTestInfo second = new AtomsPushedTestInfo(2); 92 AtomsPushedTestInfo third = new AtomsPushedTestInfo(3); 93 94 ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); 95 Callable<String> callableTask = 96 () -> { 97 mStatsLib.write(null); 98 mStatsLib.write(first); 99 mStatsLib.write(second); 100 mStatsLib.write(third); 101 return RET_SUCCESS; 102 }; 103 int delay = 100; 104 ScheduledFuture<String> future = 105 executor.schedule(callableTask, delay, TimeUnit.MILLISECONDS); 106 String result; 107 try { 108 result = future.get(); 109 } catch (ExecutionException | InterruptedException e) { 110 result = RET_FAILED; 111 } 112 113 assertEquals(result, RET_SUCCESS); 114 verify(mMockStorage, timeout(300).times(3)).appendPushedAtoms(any(AtomsPushed.class)); 115 } 116 117 @Test testRegisterPulledAtomCallback()118 public void testRegisterPulledAtomCallback() { 119 AtomsPulledTestInfo first = new AtomsPulledTestInfo(); 120 mStatsLib.registerPulledAtomCallback(first.getStatsId(), mMockPulledCallback); 121 verify(mMockPulledAtomCallback).registerAtom(first.getStatsId(), mMockPulledCallback); 122 } 123 124 @Test testNullStorage()125 public void testNullStorage() { 126 when(mMockPulledAtomCallback.getStatsLibStorage()).thenReturn(null); 127 128 mStatsLib.onWritePushedAtom(new AtomsPushedTestInfo()); 129 mStatsLib.append(new AtomsPulledTestInfo()); 130 verify(mMockStorage, never()).appendPushedAtoms(any()); 131 verify(mMockStorage, never()).appendPulledAtoms(any()); 132 } 133 134 @Test testAppendPulledAtom()135 public void testAppendPulledAtom() { 136 final int type1 = 1; 137 final int type2 = 2; 138 Random random = new Random(); 139 int count1 = random.nextInt(100); 140 int count2 = random.nextInt(1000); 141 int count3 = random.nextInt(10000); 142 int count4 = random.nextInt(100000); 143 144 mStatsLib.append(null); 145 mStatsLib.append(new AtomsPulledTestInfo(type1, count1)); 146 mStatsLib.append(new AtomsPulledTestInfo(type1, count2)); 147 mStatsLib.append(new AtomsPulledTestInfo(type2, count3)); 148 mStatsLib.append(new AtomsPulledTestInfo(type2, count4)); 149 150 verify(mMockStorage, times(4)).appendPulledAtoms(any()); 151 } 152 } 153