1/* 2 * Copyright (C) 2016, 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 17package com.android.server.connectivity; 18 19import android.content.Context; 20import android.net.ConnectivityMetricsEvent; 21import android.os.Bundle; 22import android.os.RemoteException; 23import static android.net.ConnectivityMetricsEvent.Reference; 24 25import junit.framework.TestCase; 26import org.junit.Before; 27import org.junit.Test; 28import static org.junit.Assert.assertEquals; 29import static org.junit.Assert.assertArrayEquals; 30 31import org.mockito.Mock; 32import org.mockito.MockitoAnnotations; 33 34import java.io.FileDescriptor; 35import java.io.FileOutputStream; 36import java.util.Arrays; 37import java.util.Comparator; 38import java.util.concurrent.CountDownLatch; 39import java.util.concurrent.TimeUnit; 40 41/* 42 * TODO: 43 * - allow overriding MetricsLoggerService constants in tests. 44 * - test intents are correctly sent after the notification threshold. 45 * - test oldest events are correctly pushed out when internal deque is full. 46 * - test throttling triggers correctly. 47 */ 48public class MetricsLoggerServiceTest extends TestCase { 49 50 static final int COMPONENT_TAG = 1; 51 static final long N_EVENTS = 10L; 52 static final ConnectivityMetricsEvent EVENTS[] = new ConnectivityMetricsEvent[(int)N_EVENTS]; 53 static { 54 for (int i = 0; i < N_EVENTS; i++) { 55 EVENTS[i] = new ConnectivityMetricsEvent(i, COMPONENT_TAG, i, new Bundle()); 56 } 57 } 58 59 static final ConnectivityMetricsEvent NO_EVENTS[] = new ConnectivityMetricsEvent[0]; 60 61 @Mock Context mContext; 62 MetricsLoggerService mService; 63 64 public void setUp() { 65 MockitoAnnotations.initMocks(this); 66 mService = new MetricsLoggerService(mContext); 67 mService.onStart(); 68 } 69 70 public void testGetNoEvents() throws Exception { 71 Reference r = new Reference(0); 72 assertArrayEquals(NO_EVENTS, mService.mBinder.getEvents(r)); 73 assertEquals(0, r.getValue()); 74 } 75 76 public void testLogAndGetEvents() throws Exception { 77 mService.mBinder.logEvents(EVENTS); 78 79 Reference r = new Reference(0); 80 81 assertArrayEquals(EVENTS, mService.mBinder.getEvents(r)); 82 assertEquals(N_EVENTS, r.getValue()); 83 84 assertArrayEquals(NO_EVENTS, mService.mBinder.getEvents(r)); 85 assertEquals(N_EVENTS, r.getValue()); 86 } 87 88 public void testLogOneByOne() throws Exception { 89 for (ConnectivityMetricsEvent ev : EVENTS) { 90 mService.mBinder.logEvent(ev); 91 } 92 93 Reference r = new Reference(0); 94 95 assertArrayEquals(EVENTS, mService.mBinder.getEvents(r)); 96 assertEquals(N_EVENTS, r.getValue()); 97 98 assertArrayEquals(NO_EVENTS, mService.mBinder.getEvents(r)); 99 assertEquals(N_EVENTS, r.getValue()); 100 } 101 102 public void testInterleavedLogAndGet() throws Exception { 103 mService.mBinder.logEvents(Arrays.copyOfRange(EVENTS, 0, 3)); 104 105 Reference r = new Reference(0); 106 107 assertArrayEquals(Arrays.copyOfRange(EVENTS, 0, 3), mService.mBinder.getEvents(r)); 108 assertEquals(3, r.getValue()); 109 110 mService.mBinder.logEvents(Arrays.copyOfRange(EVENTS, 3, 8)); 111 mService.mBinder.logEvents(Arrays.copyOfRange(EVENTS, 8, 10)); 112 113 assertArrayEquals(Arrays.copyOfRange(EVENTS, 3, 10), mService.mBinder.getEvents(r)); 114 assertEquals(N_EVENTS, r.getValue()); 115 116 assertArrayEquals(NO_EVENTS, mService.mBinder.getEvents(r)); 117 assertEquals(N_EVENTS, r.getValue()); 118 } 119 120 public void testMultipleGetAll() throws Exception { 121 mService.mBinder.logEvents(Arrays.copyOf(EVENTS, 3)); 122 123 Reference r1 = new Reference(0); 124 assertArrayEquals(Arrays.copyOf(EVENTS, 3), mService.mBinder.getEvents(r1)); 125 assertEquals(3, r1.getValue()); 126 127 mService.mBinder.logEvents(Arrays.copyOfRange(EVENTS, 3, 10)); 128 129 Reference r2 = new Reference(0); 130 assertArrayEquals(EVENTS, mService.mBinder.getEvents(r2)); 131 assertEquals(N_EVENTS, r2.getValue()); 132 } 133 134 public void testLogAndDumpConcurrently() throws Exception { 135 for (int i = 0; i < 50; i++) { 136 mContext = null; 137 mService = null; 138 setUp(); 139 logAndDumpConcurrently(); 140 } 141 } 142 143 public void logAndDumpConcurrently() throws Exception { 144 final CountDownLatch latch = new CountDownLatch((int)N_EVENTS); 145 final FileDescriptor fd = new FileOutputStream("/dev/null").getFD(); 146 147 for (ConnectivityMetricsEvent ev : EVENTS) { 148 new Thread() { 149 public void run() { 150 mService.mBinder.logEvent(ev); 151 latch.countDown(); 152 } 153 }.start(); 154 } 155 156 new Thread() { 157 public void run() { 158 while (latch.getCount() > 0) { 159 mService.mBinder.dump(fd, new String[]{"--all"}); 160 } 161 } 162 }.start(); 163 164 latch.await(100, TimeUnit.MILLISECONDS); 165 166 Reference r = new Reference(0); 167 ConnectivityMetricsEvent[] got = mService.mBinder.getEvents(r); 168 Arrays.sort(got, new EventComparator()); 169 assertArrayEquals(EVENTS, got); 170 assertEquals(N_EVENTS, r.getValue()); 171 } 172 173 static class EventComparator implements Comparator<ConnectivityMetricsEvent> { 174 public int compare(ConnectivityMetricsEvent ev1, ConnectivityMetricsEvent ev2) { 175 return Long.compare(ev1.timestamp, ev2.timestamp); 176 } 177 public boolean equal(Object o) { 178 return o instanceof EventComparator; 179 } 180 }; 181} 182