100a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi/*
200a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi * Copyright (C) 2016, The Android Open Source Project
300a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi *
400a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi * Licensed under the Apache License, Version 2.0 (the "License");
500a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi * you may not use this file except in compliance with the License.
600a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi * You may obtain a copy of the License at
700a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi *
800a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi *      http://www.apache.org/licenses/LICENSE-2.0
900a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi *
1000a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi * Unless required by applicable law or agreed to in writing, software
1100a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi * distributed under the License is distributed on an "AS IS" BASIS,
1200a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1300a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi * See the License for the specific language governing permissions and
1400a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi * limitations under the License.
1500a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi */
1600a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi
1700a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichipackage com.android.server.connectivity;
1800a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi
195eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichiimport static android.net.metrics.INetdEventListener.EVENT_GETADDRINFO;
205eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichiimport static android.net.metrics.INetdEventListener.EVENT_GETHOSTBYNAME;
210719940ce4c877c3b627b276accba9ebcfdeeeefGlen Kuhneimport static org.mockito.Mockito.timeout;
220719940ce4c877c3b627b276accba9ebcfdeeeefGlen Kuhneimport static org.mockito.Mockito.verify;
235eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichiimport static org.mockito.Mockito.when;
245eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichiimport static org.junit.Assert.assertEquals;
255eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichiimport static org.junit.Assert.assertFalse;
265eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichiimport static org.junit.Assert.assertTrue;
275eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichiimport static org.junit.Assert.fail;
280719940ce4c877c3b627b276accba9ebcfdeeeefGlen Kuhne
2900a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichiimport android.content.Context;
305eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichiimport android.net.ConnectivityManager;
3100a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichiimport android.net.ConnectivityMetricsEvent;
3200a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichiimport android.net.IIpConnectivityMetrics;
335eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichiimport android.net.Network;
345eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichiimport android.net.NetworkCapabilities;
35e1c173d2240a8eedf7685c9371087dc047a6931fHugo Benichiimport android.net.metrics.ApfProgramEvent;
3600a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichiimport android.net.metrics.ApfStats;
3700a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichiimport android.net.metrics.DefaultNetworkEvent;
3800a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichiimport android.net.metrics.DhcpClientEvent;
3900a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichiimport android.net.metrics.IpConnectivityLog;
4000a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichiimport android.net.metrics.IpManagerEvent;
4100a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichiimport android.net.metrics.IpReachabilityEvent;
4200a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichiimport android.net.metrics.RaEvent;
4300a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichiimport android.net.metrics.ValidationProbeEvent;
445eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichiimport android.system.OsConstants;
4500a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichiimport android.os.Parcelable;
465eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichiimport android.support.test.runner.AndroidJUnit4;
4780df43ea8a4286f2b7e0678be35dbca3f16f3766Hugo Benichiimport android.test.suitebuilder.annotation.SmallTest;
4800a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichiimport android.util.Base64;
49383db5ebcc3a4a615faf249bf4f126f42e80b82eTamas Berghammerimport com.android.server.connectivity.metrics.nano.IpConnectivityLogClass;
5000a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichiimport java.io.PrintWriter;
5100a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichiimport java.io.StringWriter;
5200a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichiimport java.util.Collections;
5300a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichiimport java.util.Comparator;
5400a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichiimport java.util.Iterator;
5500a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichiimport java.util.List;
5680df43ea8a4286f2b7e0678be35dbca3f16f3766Hugo Benichiimport org.mockito.ArgumentCaptor;
5780df43ea8a4286f2b7e0678be35dbca3f16f3766Hugo Benichiimport org.mockito.Mock;
5880df43ea8a4286f2b7e0678be35dbca3f16f3766Hugo Benichiimport org.mockito.MockitoAnnotations;
595eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichiimport org.junit.Before;
605eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichiimport org.junit.Test;
615eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichiimport org.junit.runner.RunWith;
6200a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi
635eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi@RunWith(AndroidJUnit4.class)
645eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi@SmallTest
655eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichipublic class IpConnectivityMetricsTest {
6600a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi    static final IpReachabilityEvent FAKE_EV =
67948a85948dcccea4aaa9d70a74405308581b0925Hugo Benichi            new IpReachabilityEvent(IpReachabilityEvent.NUD_FAILED);
6800a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi
695eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi    private static final String EXAMPLE_IPV4 = "192.0.2.1";
705eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi    private static final String EXAMPLE_IPV6 = "2001:db8:1200::2:1";
715eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi
7200a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi    @Mock Context mCtx;
7300a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi    @Mock IIpConnectivityMetrics mMockService;
745eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi    @Mock ConnectivityManager mCm;
7500a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi
7600a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi    IpConnectivityMetrics mService;
775eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi    NetdEventListenerService mNetdListener;
7800a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi
795eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi    @Before
8000a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi    public void setUp() {
8100a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        MockitoAnnotations.initMocks(this);
8205686dbb6b965eb1a54591d2ed2334337886c6eeHugo Benichi        mService = new IpConnectivityMetrics(mCtx, (ctx) -> 2000);
835eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi        mNetdListener = new NetdEventListenerService(mCm);
845eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi        mService.mNetdListener = mNetdListener;
8500a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi    }
8600a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi
875eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi    @Test
8800a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi    public void testLoggingEvents() throws Exception {
8900a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        IpConnectivityLog logger = new IpConnectivityLog(mMockService);
9000a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi
9100a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        assertTrue(logger.log(1, FAKE_EV));
9200a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        assertTrue(logger.log(2, FAKE_EV));
9300a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        assertTrue(logger.log(3, FAKE_EV));
9400a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi
9500a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        List<ConnectivityMetricsEvent> got = verifyEvents(3);
9600a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        assertEventsEqual(expectedEvent(1), got.get(0));
9700a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        assertEventsEqual(expectedEvent(2), got.get(1));
9800a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        assertEventsEqual(expectedEvent(3), got.get(2));
9900a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi    }
10000a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi
1015eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi    @Test
10200a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi    public void testLoggingEventsWithMultipleCallers() throws Exception {
10300a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        IpConnectivityLog logger = new IpConnectivityLog(mMockService);
10400a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi
10500a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        final int nCallers = 10;
10600a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        final int nEvents = 10;
10700a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        for (int n = 0; n < nCallers; n++) {
10800a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi            final int i = n;
10900a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi            new Thread() {
11000a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                public void run() {
11100a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                    for (int j = 0; j < nEvents; j++) {
112946b7e424e0e4d5bffc65ef405f32b966d192d3cHugo Benichi                        assertTrue(logger.log(1 + i * 100 + j, FAKE_EV));
11300a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                    }
11400a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                }
11500a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi            }.start();
11600a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        }
11700a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi
1185eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi        List<ConnectivityMetricsEvent> got = verifyEvents(nCallers * nEvents, 200);
11900a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        Collections.sort(got, EVENT_COMPARATOR);
12000a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        Iterator<ConnectivityMetricsEvent> iter = got.iterator();
12100a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        for (int i = 0; i < nCallers; i++) {
12200a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi            for (int j = 0; j < nEvents; j++) {
123946b7e424e0e4d5bffc65ef405f32b966d192d3cHugo Benichi                int expectedTimestamp = 1 + i * 100 + j;
12400a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                assertEventsEqual(expectedEvent(expectedTimestamp), iter.next());
12500a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi            }
12600a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        }
12700a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi    }
12800a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi
1295eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi    @Test
13000a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi    public void testBufferFlushing() {
13100a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        String output1 = getdump("flush");
13200a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        assertEquals("", output1);
13300a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi
13400a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        new IpConnectivityLog(mService.impl).log(1, FAKE_EV);
13500a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        String output2 = getdump("flush");
13600a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        assertFalse("".equals(output2));
13700a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi
13800a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        String output3 = getdump("flush");
13900a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        assertEquals("", output3);
14000a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi    }
14100a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi
1425eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi    @Test
143e1c173d2240a8eedf7685c9371087dc047a6931fHugo Benichi    public void testRateLimiting() {
144e1c173d2240a8eedf7685c9371087dc047a6931fHugo Benichi        final IpConnectivityLog logger = new IpConnectivityLog(mService.impl);
14522d9b2d430c9a4fe17b54811bb77289b821e32dbHugo Benichi        final ApfProgramEvent ev = new ApfProgramEvent();
146e1c173d2240a8eedf7685c9371087dc047a6931fHugo Benichi        final long fakeTimestamp = 1;
147e1c173d2240a8eedf7685c9371087dc047a6931fHugo Benichi
148e1c173d2240a8eedf7685c9371087dc047a6931fHugo Benichi        int attempt = 100; // More than burst quota, but less than buffer size.
149e1c173d2240a8eedf7685c9371087dc047a6931fHugo Benichi        for (int i = 0; i < attempt; i++) {
150e1c173d2240a8eedf7685c9371087dc047a6931fHugo Benichi            logger.log(ev);
151e1c173d2240a8eedf7685c9371087dc047a6931fHugo Benichi        }
152e1c173d2240a8eedf7685c9371087dc047a6931fHugo Benichi
153e1c173d2240a8eedf7685c9371087dc047a6931fHugo Benichi        String output1 = getdump("flush");
154e1c173d2240a8eedf7685c9371087dc047a6931fHugo Benichi        assertFalse("".equals(output1));
155e1c173d2240a8eedf7685c9371087dc047a6931fHugo Benichi
156e1c173d2240a8eedf7685c9371087dc047a6931fHugo Benichi        for (int i = 0; i < attempt; i++) {
157e1c173d2240a8eedf7685c9371087dc047a6931fHugo Benichi            assertFalse("expected event to be dropped", logger.log(fakeTimestamp, ev));
158e1c173d2240a8eedf7685c9371087dc047a6931fHugo Benichi        }
159e1c173d2240a8eedf7685c9371087dc047a6931fHugo Benichi
160e1c173d2240a8eedf7685c9371087dc047a6931fHugo Benichi        String output2 = getdump("flush");
161e1c173d2240a8eedf7685c9371087dc047a6931fHugo Benichi        assertEquals("", output2);
162e1c173d2240a8eedf7685c9371087dc047a6931fHugo Benichi    }
163e1c173d2240a8eedf7685c9371087dc047a6931fHugo Benichi
1645eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi    @Test
1655eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi    public void testEndToEndLogging() throws Exception {
166f684050e8f52c773f59a1bedca6efb56647e858cHugo Benichi        // TODO: instead of comparing textpb to textpb, parse textpb and compare proto to proto.
16700a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        IpConnectivityLog logger = new IpConnectivityLog(mService.impl);
16800a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi
1695eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi        NetworkCapabilities ncWifi = new NetworkCapabilities();
1705eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi        NetworkCapabilities ncCell = new NetworkCapabilities();
1715eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi        ncWifi.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
1725eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi        ncCell.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
1735eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi
1745eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi        when(mCm.getNetworkCapabilities(new Network(100))).thenReturn(ncWifi);
1755eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi        when(mCm.getNetworkCapabilities(new Network(101))).thenReturn(ncCell);
1765eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi
17722d9b2d430c9a4fe17b54811bb77289b821e32dbHugo Benichi        ApfStats apfStats = new ApfStats();
17822d9b2d430c9a4fe17b54811bb77289b821e32dbHugo Benichi        apfStats.durationMs = 45000;
17922d9b2d430c9a4fe17b54811bb77289b821e32dbHugo Benichi        apfStats.receivedRas = 10;
18022d9b2d430c9a4fe17b54811bb77289b821e32dbHugo Benichi        apfStats.matchingRas = 2;
18122d9b2d430c9a4fe17b54811bb77289b821e32dbHugo Benichi        apfStats.droppedRas = 2;
18222d9b2d430c9a4fe17b54811bb77289b821e32dbHugo Benichi        apfStats.parseErrors = 2;
18322d9b2d430c9a4fe17b54811bb77289b821e32dbHugo Benichi        apfStats.zeroLifetimeRas = 1;
18422d9b2d430c9a4fe17b54811bb77289b821e32dbHugo Benichi        apfStats.programUpdates = 4;
18522d9b2d430c9a4fe17b54811bb77289b821e32dbHugo Benichi        apfStats.programUpdatesAll = 7;
18622d9b2d430c9a4fe17b54811bb77289b821e32dbHugo Benichi        apfStats.programUpdatesAllowingMulticast = 3;
18722d9b2d430c9a4fe17b54811bb77289b821e32dbHugo Benichi        apfStats.maxProgramSize = 2048;
188f927f0c52e7df5b057e7d28888c3cfed164d241aHugo Benichi
189f927f0c52e7df5b057e7d28888c3cfed164d241aHugo Benichi        ValidationProbeEvent validationEv = new ValidationProbeEvent();
190f927f0c52e7df5b057e7d28888c3cfed164d241aHugo Benichi        validationEv.durationMs = 40730;
191f927f0c52e7df5b057e7d28888c3cfed164d241aHugo Benichi        validationEv.probeType = ValidationProbeEvent.PROBE_HTTP;
192f927f0c52e7df5b057e7d28888c3cfed164d241aHugo Benichi        validationEv.returnCode = 204;
193f927f0c52e7df5b057e7d28888c3cfed164d241aHugo Benichi
19400a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        Parcelable[] events = {
195948a85948dcccea4aaa9d70a74405308581b0925Hugo Benichi            new IpReachabilityEvent(IpReachabilityEvent.NUD_FAILED),
196948a85948dcccea4aaa9d70a74405308581b0925Hugo Benichi            new DhcpClientEvent("SomeState", 192),
19700a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi            new DefaultNetworkEvent(102, new int[]{1,2,3}, 101, true, false),
198948a85948dcccea4aaa9d70a74405308581b0925Hugo Benichi            new IpManagerEvent(IpManagerEvent.PROVISIONING_OK, 5678),
199f927f0c52e7df5b057e7d28888c3cfed164d241aHugo Benichi            validationEv,
20022d9b2d430c9a4fe17b54811bb77289b821e32dbHugo Benichi            apfStats,
20100a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi            new RaEvent(2000, 400, 300, -1, 1000, -1)
20200a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        };
20300a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi
20400a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        for (int i = 0; i < events.length; i++) {
205948a85948dcccea4aaa9d70a74405308581b0925Hugo Benichi            ConnectivityMetricsEvent ev = new ConnectivityMetricsEvent();
206948a85948dcccea4aaa9d70a74405308581b0925Hugo Benichi            ev.timestamp = 100 * (i + 1);
207948a85948dcccea4aaa9d70a74405308581b0925Hugo Benichi            ev.ifname = "wlan0";
208948a85948dcccea4aaa9d70a74405308581b0925Hugo Benichi            ev.data = events[i];
209948a85948dcccea4aaa9d70a74405308581b0925Hugo Benichi            logger.log(ev);
21000a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        }
21100a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi
2125eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi        // netId, errno, latency, destination
2135eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi        connectEvent(100, OsConstants.EALREADY, 0, EXAMPLE_IPV4);
2145eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi        connectEvent(100, OsConstants.EINPROGRESS, 0, EXAMPLE_IPV6);
2155eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi        connectEvent(100, 0, 110, EXAMPLE_IPV4);
2165eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi        connectEvent(101, 0, 23, EXAMPLE_IPV4);
2175eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi        connectEvent(101, 0, 45, EXAMPLE_IPV6);
2185eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi        connectEvent(100, OsConstants.EAGAIN, 0, EXAMPLE_IPV4);
2195eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi
2205eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi        // netId, type, return code, latency
2215eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi        dnsEvent(100, EVENT_GETADDRINFO, 0, 3456);
2225eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi        dnsEvent(100, EVENT_GETADDRINFO, 3, 45);
2235eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi        dnsEvent(100, EVENT_GETHOSTBYNAME, 0, 638);
2245eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi        dnsEvent(101, EVENT_GETADDRINFO, 0, 56);
2255eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi        dnsEvent(101, EVENT_GETHOSTBYNAME, 0, 34);
2265eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi
2272a5cfb9738867da634a3bf64ccef881aaefbfce5Hugo Benichi        String want = String.join("\n",
22800a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "dropped_events: 0",
22900a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "events <",
230f684050e8f52c773f59a1bedca6efb56647e858cHugo Benichi                "  if_name: \"\"",
231948a85948dcccea4aaa9d70a74405308581b0925Hugo Benichi                "  link_layer: 4",
232f684050e8f52c773f59a1bedca6efb56647e858cHugo Benichi                "  network_id: 0",
23380df43ea8a4286f2b7e0678be35dbca3f16f3766Hugo Benichi                "  time_ms: 100",
234f684050e8f52c773f59a1bedca6efb56647e858cHugo Benichi                "  transports: 0",
23500a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "  ip_reachability_event <",
23600a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "    event_type: 512",
237948a85948dcccea4aaa9d70a74405308581b0925Hugo Benichi                "    if_name: \"\"",
23800a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "  >",
23900a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                ">",
24000a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "events <",
241f684050e8f52c773f59a1bedca6efb56647e858cHugo Benichi                "  if_name: \"\"",
242948a85948dcccea4aaa9d70a74405308581b0925Hugo Benichi                "  link_layer: 4",
243f684050e8f52c773f59a1bedca6efb56647e858cHugo Benichi                "  network_id: 0",
24480df43ea8a4286f2b7e0678be35dbca3f16f3766Hugo Benichi                "  time_ms: 200",
245f684050e8f52c773f59a1bedca6efb56647e858cHugo Benichi                "  transports: 0",
24600a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "  dhcp_event <",
24700a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "    duration_ms: 192",
248948a85948dcccea4aaa9d70a74405308581b0925Hugo Benichi                "    if_name: \"\"",
24900a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "    state_transition: \"SomeState\"",
25000a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "  >",
25100a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                ">",
25200a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "events <",
253f684050e8f52c773f59a1bedca6efb56647e858cHugo Benichi                "  if_name: \"\"",
254948a85948dcccea4aaa9d70a74405308581b0925Hugo Benichi                "  link_layer: 4",
255f684050e8f52c773f59a1bedca6efb56647e858cHugo Benichi                "  network_id: 0",
25680df43ea8a4286f2b7e0678be35dbca3f16f3766Hugo Benichi                "  time_ms: 300",
257f684050e8f52c773f59a1bedca6efb56647e858cHugo Benichi                "  transports: 0",
25800a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "  default_network_event <",
25900a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "    network_id <",
26000a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "      network_id: 102",
26100a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "    >",
26200a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "    previous_network_id <",
26300a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "      network_id: 101",
26400a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "    >",
26500a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "    previous_network_ip_support: 1",
26600a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "    transport_types: 1",
26700a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "    transport_types: 2",
26800a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "    transport_types: 3",
26900a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "  >",
27000a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                ">",
27100a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "events <",
272f684050e8f52c773f59a1bedca6efb56647e858cHugo Benichi                "  if_name: \"\"",
273948a85948dcccea4aaa9d70a74405308581b0925Hugo Benichi                "  link_layer: 4",
274f684050e8f52c773f59a1bedca6efb56647e858cHugo Benichi                "  network_id: 0",
27580df43ea8a4286f2b7e0678be35dbca3f16f3766Hugo Benichi                "  time_ms: 400",
276f684050e8f52c773f59a1bedca6efb56647e858cHugo Benichi                "  transports: 0",
27700a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "  ip_provisioning_event <",
27800a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "    event_type: 1",
279948a85948dcccea4aaa9d70a74405308581b0925Hugo Benichi                "    if_name: \"\"",
28000a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "    latency_ms: 5678",
28100a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "  >",
28200a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                ">",
28300a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "events <",
284f684050e8f52c773f59a1bedca6efb56647e858cHugo Benichi                "  if_name: \"\"",
285948a85948dcccea4aaa9d70a74405308581b0925Hugo Benichi                "  link_layer: 4",
286f684050e8f52c773f59a1bedca6efb56647e858cHugo Benichi                "  network_id: 0",
28700a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "  time_ms: 500",
288f684050e8f52c773f59a1bedca6efb56647e858cHugo Benichi                "  transports: 0",
28900a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "  validation_probe_event <",
29000a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "    latency_ms: 40730",
29100a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "    probe_result: 204",
29200a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "    probe_type: 1",
29300a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "  >",
29400a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                ">",
29500a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "events <",
296f684050e8f52c773f59a1bedca6efb56647e858cHugo Benichi                "  if_name: \"\"",
297948a85948dcccea4aaa9d70a74405308581b0925Hugo Benichi                "  link_layer: 4",
298f684050e8f52c773f59a1bedca6efb56647e858cHugo Benichi                "  network_id: 0",
29980df43ea8a4286f2b7e0678be35dbca3f16f3766Hugo Benichi                "  time_ms: 600",
300f684050e8f52c773f59a1bedca6efb56647e858cHugo Benichi                "  transports: 0",
30100a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "  apf_statistics <",
30200a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "    dropped_ras: 2",
30300a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "    duration_ms: 45000",
30400a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "    matching_ras: 2",
30500a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "    max_program_size: 2048",
30600a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "    parse_errors: 2",
30700a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "    program_updates: 4",
30822d9b2d430c9a4fe17b54811bb77289b821e32dbHugo Benichi                "    program_updates_all: 7",
30922d9b2d430c9a4fe17b54811bb77289b821e32dbHugo Benichi                "    program_updates_allowing_multicast: 3",
31000a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "    received_ras: 10",
31100a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "    zero_lifetime_ras: 1",
31200a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "  >",
31300a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                ">",
31400a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "events <",
315f684050e8f52c773f59a1bedca6efb56647e858cHugo Benichi                "  if_name: \"\"",
316948a85948dcccea4aaa9d70a74405308581b0925Hugo Benichi                "  link_layer: 4",
317f684050e8f52c773f59a1bedca6efb56647e858cHugo Benichi                "  network_id: 0",
31880df43ea8a4286f2b7e0678be35dbca3f16f3766Hugo Benichi                "  time_ms: 700",
319f684050e8f52c773f59a1bedca6efb56647e858cHugo Benichi                "  transports: 0",
32000a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "  ra_event <",
32100a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "    dnssl_lifetime: -1",
32200a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "    prefix_preferred_lifetime: 300",
32300a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "    prefix_valid_lifetime: 400",
32400a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "    rdnss_lifetime: 1000",
32500a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "    route_info_lifetime: -1",
32600a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "    router_lifetime: 2000",
32700a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                "  >",
328d680d4c856f54bea0c60dea74ba4204822391e49Hugo Benichi                ">",
3295eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "events <",
3305eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "  if_name: \"\"",
3315eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "  link_layer: 4",
3325eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "  network_id: 100",
3335eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "  time_ms: 0",
3345eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "  transports: 2",
3355eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "  connect_statistics <",
3365eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "    connect_blocking_count: 1",
3375eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "    connect_count: 3",
3385eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "    errnos_counters <",
3395eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "      key: 11",
3405eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "      value: 1",
3415eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "    >",
3425eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "    ipv6_addr_count: 1",
3435eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "    latencies_ms: 110",
3445eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "  >",
3455eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                ">",
3465eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "events <",
3475eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "  if_name: \"\"",
3485eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "  link_layer: 2",
3495eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "  network_id: 101",
3505eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "  time_ms: 0",
3515eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "  transports: 1",
3525eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "  connect_statistics <",
3535eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "    connect_blocking_count: 2",
3545eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "    connect_count: 2",
3555eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "    ipv6_addr_count: 1",
3565eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "    latencies_ms: 23",
3575eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "    latencies_ms: 45",
3585eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "  >",
3595eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                ">",
3605eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "events <",
3615eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "  if_name: \"\"",
3625eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "  link_layer: 4",
3635eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "  network_id: 100",
3645eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "  time_ms: 0",
3655eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "  transports: 2",
3665eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "  dns_lookup_batch <",
3675eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "    event_types: 1",
3685eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "    event_types: 1",
3695eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "    event_types: 2",
3705eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "    latencies_ms: 3456",
3715eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "    latencies_ms: 45",
3725eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "    latencies_ms: 638",
3735eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "    return_codes: 0",
3745eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "    return_codes: 3",
3755eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "    return_codes: 0",
3765eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "  >",
3775eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                ">",
3785eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "events <",
3795eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "  if_name: \"\"",
3805eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "  link_layer: 2",
3815eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "  network_id: 101",
3825eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "  time_ms: 0",
3835eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "  transports: 1",
3845eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "  dns_lookup_batch <",
3855eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "    event_types: 1",
3865eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "    event_types: 2",
3875eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "    latencies_ms: 56",
3885eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "    latencies_ms: 34",
3895eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "    return_codes: 0",
3905eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "    return_codes: 0",
3915eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                "  >",
3925eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi                ">",
3932a5cfb9738867da634a3bf64ccef881aaefbfce5Hugo Benichi                "version: 2\n");
39400a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi
39500a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        verifySerialization(want, getdump("flush"));
39600a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi    }
39700a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi
39800a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi    String getdump(String ... command) {
39900a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        StringWriter buffer = new StringWriter();
40000a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        PrintWriter writer = new PrintWriter(buffer);
40100a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        mService.impl.dump(null, writer, command);
40200a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        return buffer.toString();
40300a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi    }
40400a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi
4055eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi    void connectEvent(int netid, int error, int latencyMs, String ipAddr) throws Exception {
4065eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi        mNetdListener.onConnectEvent(netid, error, latencyMs, ipAddr, 80, 1);
4075eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi    }
4085eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi
4095eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi    void dnsEvent(int netId, int type, int result, int latency) throws Exception {
4105eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi        mNetdListener.onDnsEvent(netId, type, result, latency, "", null, 0, 0);
4115eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi    }
4125eb9053c4e8c788b83cfcfd7bfd39f628dd4ca45Hugo Benichi
41300a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi    List<ConnectivityMetricsEvent> verifyEvents(int n, int timeoutMs) throws Exception {
41400a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        ArgumentCaptor<ConnectivityMetricsEvent> captor =
41500a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi                ArgumentCaptor.forClass(ConnectivityMetricsEvent.class);
41600a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        verify(mMockService, timeout(timeoutMs).times(n)).logEvent(captor.capture());
41700a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        return captor.getAllValues();
41800a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi    }
41900a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi
42000a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi    List<ConnectivityMetricsEvent> verifyEvents(int n) throws Exception {
42100a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        return verifyEvents(n, 10);
42200a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi    }
42300a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi
42400a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi    static void verifySerialization(String want, String output) {
42500a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        try {
42600a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi            byte[] got = Base64.decode(output, Base64.DEFAULT);
42700a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi            IpConnectivityLogClass.IpConnectivityLog log =
4280719940ce4c877c3b627b276accba9ebcfdeeeefGlen Kuhne                    IpConnectivityLogClass.IpConnectivityLog.parseFrom(got);
42900a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi            assertEquals(want, log.toString());
43000a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        } catch (Exception e) {
43100a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi            fail(e.toString());
43200a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        }
43300a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi    }
43400a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi
43500a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi    static String joinLines(String ... elems) {
43600a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        StringBuilder b = new StringBuilder();
43700a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        for (String s : elems) {
43800a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi            b.append(s).append("\n");
43900a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        }
44000a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        return b.toString();
44100a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi    }
44200a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi
44300a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi    static ConnectivityMetricsEvent expectedEvent(int timestamp) {
444ec27c4d9f33615be1f94d6bb5c5fd1358580ac05Hugo Benichi        ConnectivityMetricsEvent ev = new ConnectivityMetricsEvent();
445ec27c4d9f33615be1f94d6bb5c5fd1358580ac05Hugo Benichi        ev.timestamp = timestamp;
446ec27c4d9f33615be1f94d6bb5c5fd1358580ac05Hugo Benichi        ev.data = FAKE_EV;
447ec27c4d9f33615be1f94d6bb5c5fd1358580ac05Hugo Benichi        return ev;
44800a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi    }
44900a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi
45000a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi    /** Outer equality for ConnectivityMetricsEvent to avoid overriding equals() and hashCode(). */
45100a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi    static void assertEventsEqual(ConnectivityMetricsEvent expected, ConnectivityMetricsEvent got) {
45200a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        assertEquals(expected.timestamp, got.timestamp);
45300a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi        assertEquals(expected.data, got.data);
45400a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi    }
45500a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi
45600a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi    static final Comparator<ConnectivityMetricsEvent> EVENT_COMPARATOR =
4570d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichi        Comparator.comparingLong((ev) -> ev.timestamp);
45800a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi}
459