15e055187bea4f4c96799a3e7fcc5aaaf57740ea3Hugo Benichi/*
25e055187bea4f4c96799a3e7fcc5aaaf57740ea3Hugo Benichi * Copyright (C) 2016, The Android Open Source Project
35e055187bea4f4c96799a3e7fcc5aaaf57740ea3Hugo Benichi *
45e055187bea4f4c96799a3e7fcc5aaaf57740ea3Hugo Benichi * Licensed under the Apache License, Version 2.0 (the "License");
55e055187bea4f4c96799a3e7fcc5aaaf57740ea3Hugo Benichi * you may not use this file except in compliance with the License.
65e055187bea4f4c96799a3e7fcc5aaaf57740ea3Hugo Benichi * You may obtain a copy of the License at
75e055187bea4f4c96799a3e7fcc5aaaf57740ea3Hugo Benichi *
85e055187bea4f4c96799a3e7fcc5aaaf57740ea3Hugo Benichi *      http://www.apache.org/licenses/LICENSE-2.0
95e055187bea4f4c96799a3e7fcc5aaaf57740ea3Hugo Benichi *
105e055187bea4f4c96799a3e7fcc5aaaf57740ea3Hugo Benichi * Unless required by applicable law or agreed to in writing, software
115e055187bea4f4c96799a3e7fcc5aaaf57740ea3Hugo Benichi * distributed under the License is distributed on an "AS IS" BASIS,
125e055187bea4f4c96799a3e7fcc5aaaf57740ea3Hugo Benichi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135e055187bea4f4c96799a3e7fcc5aaaf57740ea3Hugo Benichi * See the License for the specific language governing permissions and
145e055187bea4f4c96799a3e7fcc5aaaf57740ea3Hugo Benichi * limitations under the License.
155e055187bea4f4c96799a3e7fcc5aaaf57740ea3Hugo Benichi */
165e055187bea4f4c96799a3e7fcc5aaaf57740ea3Hugo Benichi
175e055187bea4f4c96799a3e7fcc5aaaf57740ea3Hugo Benichipackage com.android.server.connectivity;
185e055187bea4f4c96799a3e7fcc5aaaf57740ea3Hugo Benichi
190699cf98042a64e41ee076c464eb115a6579be08Hugo Benichiimport static android.net.metrics.INetdEventListener.EVENT_GETADDRINFO;
200699cf98042a64e41ee076c464eb115a6579be08Hugo Benichiimport static android.net.metrics.INetdEventListener.EVENT_GETHOSTBYNAME;
210699cf98042a64e41ee076c464eb115a6579be08Hugo Benichiimport static org.junit.Assert.assertEquals;
221e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichiimport static org.junit.Assert.assertTrue;
230699cf98042a64e41ee076c464eb115a6579be08Hugo Benichiimport static org.junit.Assert.fail;
240699cf98042a64e41ee076c464eb115a6579be08Hugo Benichiimport static org.mockito.Mockito.any;
250699cf98042a64e41ee076c464eb115a6579be08Hugo Benichiimport static org.mockito.Mockito.mock;
260699cf98042a64e41ee076c464eb115a6579be08Hugo Benichiimport static org.mockito.Mockito.anyInt;
270699cf98042a64e41ee076c464eb115a6579be08Hugo Benichiimport static org.mockito.Mockito.eq;
280699cf98042a64e41ee076c464eb115a6579be08Hugo Benichiimport static org.mockito.Mockito.timeout;
290699cf98042a64e41ee076c464eb115a6579be08Hugo Benichiimport static org.mockito.Mockito.times;
300699cf98042a64e41ee076c464eb115a6579be08Hugo Benichiimport static org.mockito.Mockito.verify;
310699cf98042a64e41ee076c464eb115a6579be08Hugo Benichiimport static org.mockito.Mockito.when;
320699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi
330699cf98042a64e41ee076c464eb115a6579be08Hugo Benichiimport android.content.Context;
345e055187bea4f4c96799a3e7fcc5aaaf57740ea3Hugo Benichiimport android.net.ConnectivityManager;
355e055187bea4f4c96799a3e7fcc5aaaf57740ea3Hugo Benichiimport android.net.Network;
360699cf98042a64e41ee076c464eb115a6579be08Hugo Benichiimport android.net.NetworkCapabilities;
370699cf98042a64e41ee076c464eb115a6579be08Hugo Benichiimport android.support.test.runner.AndroidJUnit4;
380d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichiimport android.system.OsConstants;
39fa8a6f6220d1a0027ba7969c2d3f72690ddc6495Hugo Benichiimport android.test.suitebuilder.annotation.SmallTest;
400699cf98042a64e41ee076c464eb115a6579be08Hugo Benichiimport android.util.Base64;
41a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi
420699cf98042a64e41ee076c464eb115a6579be08Hugo Benichiimport com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.DNSLookupBatch;
430d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichiimport com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityEvent;
440699cf98042a64e41ee076c464eb115a6579be08Hugo Benichiimport com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityLog;
45a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi
460d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichiimport java.io.FileOutputStream;
470d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichiimport java.io.PrintWriter;
480699cf98042a64e41ee076c464eb115a6579be08Hugo Benichiimport java.io.StringWriter;
490d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichiimport java.util.ArrayList;
500d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichiimport java.util.Arrays;
510d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichiimport java.util.Comparator;
520d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichiimport java.util.List;
53a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi
545e055187bea4f4c96799a3e7fcc5aaaf57740ea3Hugo Benichiimport org.junit.Before;
555e055187bea4f4c96799a3e7fcc5aaaf57740ea3Hugo Benichiimport org.junit.Test;
560699cf98042a64e41ee076c464eb115a6579be08Hugo Benichiimport org.junit.runner.RunWith;
575e055187bea4f4c96799a3e7fcc5aaaf57740ea3Hugo Benichi
580699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi@RunWith(AndroidJUnit4.class)
590699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi@SmallTest
600699cf98042a64e41ee076c464eb115a6579be08Hugo Benichipublic class NetdEventListenerServiceTest {
610d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichi    private static final String EXAMPLE_IPV4 = "192.0.2.1";
620d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichi    private static final String EXAMPLE_IPV6 = "2001:db8:1200::2:1";
630d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichi
644f26103fdd4dad3cc720f4ba2f6bf9a9b0469c22Michal Karpinski    NetdEventListenerService mNetdEventListenerService;
650699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi    ConnectivityManager mCm;
665e055187bea4f4c96799a3e7fcc5aaaf57740ea3Hugo Benichi
670699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi    @Before
685e055187bea4f4c96799a3e7fcc5aaaf57740ea3Hugo Benichi    public void setUp() {
690699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi        NetworkCapabilities ncWifi = new NetworkCapabilities();
700699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi        NetworkCapabilities ncCell = new NetworkCapabilities();
710699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi        ncWifi.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
720699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi        ncCell.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
730699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi
74dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi        mCm = mock(ConnectivityManager.class);
750699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi        when(mCm.getNetworkCapabilities(new Network(100))).thenReturn(ncWifi);
760699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi        when(mCm.getNetworkCapabilities(new Network(101))).thenReturn(ncCell);
770699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi
78dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi        mNetdEventListenerService = new NetdEventListenerService(mCm);
79dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi    }
80dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi
81dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi    @Test
821e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi    public void testWakeupEventLogging() throws Exception {
831e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi        final int BUFFER_LENGTH = NetdEventListenerService.WAKEUP_EVENT_BUFFER_LENGTH;
841e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi
851e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi        // Assert no events
861e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi        String[] events1 = listNetdEvent();
871e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi        assertEquals(new String[]{""}, events1);
881e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi
891e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi        long now = System.currentTimeMillis();
901e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi        String prefix = "iface:wlan0";
911e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi        int[] uids = { 10001, 10002, 10004, 1000, 10052, 10023, 10002, 10123, 10004 };
921e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi        for (int uid : uids) {
931e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi            mNetdEventListenerService.onWakeupEvent(prefix, uid, uid, now);
941e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi        }
951e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi
961e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi        String[] events2 = listNetdEvent();
97a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi        int expectedLength2 = uids.length + 1; // +1 for the WakeupStats line
98a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi        assertEquals(expectedLength2, events2.length);
99a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi        assertContains(events2[0], "WakeupStats");
100a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi        assertContains(events2[0], "wlan0");
1011e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi        for (int i = 0; i < uids.length; i++) {
102a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi            String got = events2[i+1];
103a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi            assertContains(got, "WakeupEvent");
1041e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi            assertContains(got, "wlan0");
1051e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi            assertContains(got, "uid: " + uids[i]);
1061e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi        }
1071e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi
1081e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi        int uid = 20000;
1091e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi        for (int i = 0; i < BUFFER_LENGTH * 2; i++) {
1101e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi            long ts = now + 10;
1111e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi            mNetdEventListenerService.onWakeupEvent(prefix, uid, uid, ts);
1121e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi        }
1131e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi
1141e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi        String[] events3 = listNetdEvent();
115a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi        int expectedLength3 = BUFFER_LENGTH + 1; // +1 for the WakeupStats line
116a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi        assertEquals(expectedLength3, events3.length);
117a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi        assertContains(events2[0], "WakeupStats");
118a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi        assertContains(events2[0], "wlan0");
119a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi        for (int i = 1; i < expectedLength3; i++) {
120a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi            String got = events3[i];
121a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi            assertContains(got, "WakeupEvent");
1221e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi            assertContains(got, "wlan0");
1231e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi            assertContains(got, "uid: " + uid);
1241e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi        }
1251e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi
1261e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi        uid = 45678;
1271e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi        mNetdEventListenerService.onWakeupEvent(prefix, uid, uid, now);
1281e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi
1291e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi        String[] events4 = listNetdEvent();
1301e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi        String lastEvent = events4[events4.length - 1];
131a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi        assertContains(lastEvent, "WakeupEvent");
1321e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi        assertContains(lastEvent, "wlan0");
1331e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi        assertContains(lastEvent, "uid: " + uid);
1341e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi    }
1351e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi
1361e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi    @Test
137a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi    public void testWakeupStatsLogging() throws Exception {
138a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi        wakeupEvent("wlan0", 1000);
139a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi        wakeupEvent("rmnet0", 10123);
140a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi        wakeupEvent("wlan0", 1000);
141a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi        wakeupEvent("rmnet0", 10008);
142a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi        wakeupEvent("wlan0", -1);
143a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi        wakeupEvent("wlan0", 10008);
144a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi        wakeupEvent("rmnet0", 1000);
145a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi        wakeupEvent("wlan0", 10004);
146a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi        wakeupEvent("wlan0", 1000);
147a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi        wakeupEvent("wlan0", 0);
148a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi        wakeupEvent("wlan0", -1);
149a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi        wakeupEvent("rmnet0", 10052);
150a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi        wakeupEvent("wlan0", 0);
151a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi        wakeupEvent("rmnet0", 1000);
152a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi        wakeupEvent("wlan0", 1010);
153a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi
154a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi        String got = flushStatistics();
155a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi        String want = String.join("\n",
156a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi                "dropped_events: 0",
157a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi                "events <",
158a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi                "  if_name: \"\"",
159a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi                "  link_layer: 2",
160a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi                "  network_id: 0",
161a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi                "  time_ms: 0",
162a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi                "  transports: 0",
163a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi                "  wakeup_stats <",
164a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi                "    application_wakeups: 3",
165a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi                "    duration_sec: 0",
1660e4b41527449cb52c479c8e5abb2a6a49cf33641Hugo Benichi                "    no_uid_wakeups: 0",
167a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi                "    non_application_wakeups: 0",
168a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi                "    root_wakeups: 0",
169a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi                "    system_wakeups: 2",
170a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi                "    total_wakeups: 5",
171a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi                "  >",
172a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi                ">",
173a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi                "events <",
174a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi                "  if_name: \"\"",
175a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi                "  link_layer: 4",
176a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi                "  network_id: 0",
177a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi                "  time_ms: 0",
178a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi                "  transports: 0",
179a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi                "  wakeup_stats <",
180a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi                "    application_wakeups: 2",
181a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi                "    duration_sec: 0",
1820e4b41527449cb52c479c8e5abb2a6a49cf33641Hugo Benichi                "    no_uid_wakeups: 2",
183a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi                "    non_application_wakeups: 1",
184a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi                "    root_wakeups: 2",
185a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi                "    system_wakeups: 3",
186a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi                "    total_wakeups: 10",
187a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi                "  >",
188a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi                ">",
189a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi                "version: 2\n");
190a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi        assertEquals(want, got);
191a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi    }
192a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi
193a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi    @Test
194dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi    public void testDnsLogging() throws Exception {
195dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi        asyncDump(100);
196dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi
1970699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi        dnsEvent(100, EVENT_GETADDRINFO, 0, 3456);
1980699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi        dnsEvent(100, EVENT_GETADDRINFO, 0, 267);
1990699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi        dnsEvent(100, EVENT_GETHOSTBYNAME, 22, 1230);
2000699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi        dnsEvent(100, EVENT_GETADDRINFO, 3, 45);
2010699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi        dnsEvent(100, EVENT_GETADDRINFO, 1, 2111);
2020699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi        dnsEvent(100, EVENT_GETADDRINFO, 0, 450);
2030699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi        dnsEvent(100, EVENT_GETHOSTBYNAME, 200, 638);
2040699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi        dnsEvent(100, EVENT_GETHOSTBYNAME, 178, 1300);
2050699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi        dnsEvent(101, EVENT_GETADDRINFO, 0, 56);
2060699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi        dnsEvent(101, EVENT_GETADDRINFO, 0, 78);
2070699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi        dnsEvent(101, EVENT_GETADDRINFO, 0, 14);
2080699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi        dnsEvent(101, EVENT_GETHOSTBYNAME, 0, 56);
2090699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi        dnsEvent(101, EVENT_GETADDRINFO, 0, 78);
2100699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi        dnsEvent(101, EVENT_GETADDRINFO, 0, 14);
2110699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi
2120699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi        String got = flushStatistics();
2130699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi        String want = String.join("\n",
2140699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "dropped_events: 0",
2150699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "events <",
2160699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "  if_name: \"\"",
2170699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "  link_layer: 4",
2180699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "  network_id: 100",
2190699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "  time_ms: 0",
2200699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "  transports: 2",
2210699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "  dns_lookup_batch <",
2220699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    event_types: 1",
2230699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    event_types: 1",
2240699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    event_types: 2",
2250699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    event_types: 1",
2260699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    event_types: 1",
2270699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    event_types: 1",
2280699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    event_types: 2",
2290699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    event_types: 2",
230822c5bf77892175d0b52aeaddf4e43c749c341f6Hugo Benichi                "    getaddrinfo_error_count: 0",
231822c5bf77892175d0b52aeaddf4e43c749c341f6Hugo Benichi                "    getaddrinfo_query_count: 0",
232822c5bf77892175d0b52aeaddf4e43c749c341f6Hugo Benichi                "    gethostbyname_error_count: 0",
233822c5bf77892175d0b52aeaddf4e43c749c341f6Hugo Benichi                "    gethostbyname_query_count: 0",
2340699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    latencies_ms: 3456",
2350699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    latencies_ms: 267",
2360699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    latencies_ms: 1230",
2370699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    latencies_ms: 45",
2380699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    latencies_ms: 2111",
2390699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    latencies_ms: 450",
2400699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    latencies_ms: 638",
2410699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    latencies_ms: 1300",
2420699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    return_codes: 0",
2430699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    return_codes: 0",
2440699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    return_codes: 22",
2450699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    return_codes: 3",
2460699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    return_codes: 1",
2470699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    return_codes: 0",
2480699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    return_codes: 200",
2490699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    return_codes: 178",
2500699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "  >",
2510699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                ">",
2520699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "events <",
2530699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "  if_name: \"\"",
2540699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "  link_layer: 2",
2550699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "  network_id: 101",
2560699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "  time_ms: 0",
2570699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "  transports: 1",
2580699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "  dns_lookup_batch <",
2590699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    event_types: 1",
2600699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    event_types: 1",
2610699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    event_types: 1",
2620699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    event_types: 2",
2630699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    event_types: 1",
2640699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    event_types: 1",
265822c5bf77892175d0b52aeaddf4e43c749c341f6Hugo Benichi                "    getaddrinfo_error_count: 0",
266822c5bf77892175d0b52aeaddf4e43c749c341f6Hugo Benichi                "    getaddrinfo_query_count: 0",
267822c5bf77892175d0b52aeaddf4e43c749c341f6Hugo Benichi                "    gethostbyname_error_count: 0",
268822c5bf77892175d0b52aeaddf4e43c749c341f6Hugo Benichi                "    gethostbyname_query_count: 0",
2690699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    latencies_ms: 56",
2700699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    latencies_ms: 78",
2710699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    latencies_ms: 14",
2720699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    latencies_ms: 56",
2730699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    latencies_ms: 78",
2740699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    latencies_ms: 14",
2750699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    return_codes: 0",
2760699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    return_codes: 0",
2770699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    return_codes: 0",
2780699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    return_codes: 0",
2790699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    return_codes: 0",
2800699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "    return_codes: 0",
2810699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "  >",
2820699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                ">",
2830699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                "version: 2\n");
2840699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi        assertEquals(want, got);
2855e055187bea4f4c96799a3e7fcc5aaaf57740ea3Hugo Benichi    }
2865e055187bea4f4c96799a3e7fcc5aaaf57740ea3Hugo Benichi
2870699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi    @Test
2880d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichi    public void testConnectLogging() throws Exception {
289dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi        asyncDump(100);
290dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi
2910d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichi        final int OK = 0;
2920d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichi        Thread[] logActions = {
2930d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichi            // ignored
294dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi            connectEventAction(100, OsConstants.EALREADY, 0, EXAMPLE_IPV4),
295dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi            connectEventAction(100, OsConstants.EALREADY, 0, EXAMPLE_IPV6),
296dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi            connectEventAction(100, OsConstants.EINPROGRESS, 0, EXAMPLE_IPV4),
297dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi            connectEventAction(101, OsConstants.EINPROGRESS, 0, EXAMPLE_IPV6),
298dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi            connectEventAction(101, OsConstants.EINPROGRESS, 0, EXAMPLE_IPV6),
2990d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichi            // valid latencies
300dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi            connectEventAction(100, OK, 110, EXAMPLE_IPV4),
301dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi            connectEventAction(100, OK, 23, EXAMPLE_IPV4),
302dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi            connectEventAction(100, OK, 45, EXAMPLE_IPV4),
303dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi            connectEventAction(101, OK, 56, EXAMPLE_IPV4),
304dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi            connectEventAction(101, OK, 523, EXAMPLE_IPV6),
305dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi            connectEventAction(101, OK, 214, EXAMPLE_IPV6),
306dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi            connectEventAction(101, OK, 67, EXAMPLE_IPV6),
3070d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichi            // errors
308dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi            connectEventAction(100, OsConstants.EPERM, 0, EXAMPLE_IPV4),
309dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi            connectEventAction(101, OsConstants.EPERM, 0, EXAMPLE_IPV4),
310dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi            connectEventAction(100, OsConstants.EAGAIN, 0, EXAMPLE_IPV4),
311dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi            connectEventAction(100, OsConstants.EACCES, 0, EXAMPLE_IPV4),
312dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi            connectEventAction(101, OsConstants.EACCES, 0, EXAMPLE_IPV4),
313dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi            connectEventAction(101, OsConstants.EACCES, 0, EXAMPLE_IPV6),
314dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi            connectEventAction(100, OsConstants.EADDRINUSE, 0, EXAMPLE_IPV4),
315dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi            connectEventAction(101, OsConstants.ETIMEDOUT, 0, EXAMPLE_IPV4),
316dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi            connectEventAction(100, OsConstants.ETIMEDOUT, 0, EXAMPLE_IPV6),
317dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi            connectEventAction(100, OsConstants.ETIMEDOUT, 0, EXAMPLE_IPV6),
318dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi            connectEventAction(101, OsConstants.ECONNREFUSED, 0, EXAMPLE_IPV4),
3190d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichi        };
3200d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichi
3210d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichi        for (Thread t : logActions) {
3220d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichi            t.start();
3230d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichi        }
3240d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichi        for (Thread t : logActions) {
3250d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichi            t.join();
3260d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichi        }
3270d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichi
328dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi        String got = flushStatistics();
3290d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichi        String want = String.join("\n",
330dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "dropped_events: 0",
331dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "events <",
332dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "  if_name: \"\"",
333dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "  link_layer: 4",
334dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "  network_id: 100",
335dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "  time_ms: 0",
336dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "  transports: 2",
337dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "  connect_statistics <",
338dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "    connect_blocking_count: 3",
339dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "    connect_count: 6",
340dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "    errnos_counters <",
341dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "      key: 1",
342dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "      value: 1",
343dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "    >",
344dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "    errnos_counters <",
345dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "      key: 11",
346dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "      value: 1",
347dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "    >",
348dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "    errnos_counters <",
349dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "      key: 13",
350dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "      value: 1",
351dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "    >",
352dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "    errnos_counters <",
353dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "      key: 98",
354dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "      value: 1",
355dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "    >",
356dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "    errnos_counters <",
357dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "      key: 110",
358dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "      value: 2",
359dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "    >",
360dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "    ipv6_addr_count: 1",
361dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "    latencies_ms: 23",
362dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "    latencies_ms: 45",
363dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "    latencies_ms: 110",
3640d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichi                "  >",
365dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                ">",
366dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "events <",
367dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "  if_name: \"\"",
368dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "  link_layer: 2",
369dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "  network_id: 101",
370dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "  time_ms: 0",
371dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "  transports: 1",
372dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "  connect_statistics <",
373dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "    connect_blocking_count: 4",
374dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "    connect_count: 6",
375dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "    errnos_counters <",
376dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "      key: 1",
377dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "      value: 1",
378dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "    >",
379dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "    errnos_counters <",
380dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "      key: 13",
381dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "      value: 2",
382dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "    >",
383dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "    errnos_counters <",
384dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "      key: 110",
385dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "      value: 1",
386dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "    >",
387dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "    errnos_counters <",
388dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "      key: 111",
389dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "      value: 1",
390dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "    >",
391dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "    ipv6_addr_count: 5",
392dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "    latencies_ms: 56",
393dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "    latencies_ms: 67",
394dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "    latencies_ms: 214",
395dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "    latencies_ms: 523",
3960d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichi                "  >",
397dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                ">",
398dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                "version: 2\n");
399dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi        assertEquals(want, got);
4000d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichi    }
4010d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichi
402dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi    Thread connectEventAction(int netId, int error, int latencyMs, String ipAddr) {
4030d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichi        return new Thread(() -> {
4040d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichi            try {
405dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                mNetdEventListenerService.onConnectEvent(netId, error, latencyMs, ipAddr, 80, 1);
4060d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichi            } catch (Exception e) {
4070d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichi                fail(e.toString());
4080d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichi            }
4090d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichi        });
4100d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichi    }
4110d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichi
4120699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi    void dnsEvent(int netId, int type, int result, int latency) throws Exception {
4130699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi        mNetdEventListenerService.onDnsEvent(netId, type, result, latency, "", null, 0, 0);
4145e055187bea4f4c96799a3e7fcc5aaaf57740ea3Hugo Benichi    }
4155e055187bea4f4c96799a3e7fcc5aaaf57740ea3Hugo Benichi
416a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi    void wakeupEvent(String iface, int uid) throws Exception {
417a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi        String prefix = NetdEventListenerService.WAKEUP_EVENT_IFACE_PREFIX + iface;
418a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi        mNetdEventListenerService.onWakeupEvent(prefix, uid, uid, 0);
419a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi    }
420a87b15c95f01b80c6bcfa71cbf66e8456342ea28Hugo Benichi
421dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi    void asyncDump(long durationMs) throws Exception {
4220699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi        final long stop = System.currentTimeMillis() + durationMs;
4230699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi        final PrintWriter pw = new PrintWriter(new FileOutputStream("/dev/null"));
424dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi        new Thread(() -> {
4250699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi            while (System.currentTimeMillis() < stop) {
4260699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                mNetdEventListenerService.dump(pw);
4270699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi            }
428dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi        }).start();
4290d4a398b7846f26e4452180915ecb5a9d4566148Hugo Benichi    }
4300699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi
4310699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi    // TODO: instead of comparing textpb to textpb, parse textpb and compare proto to proto.
4320699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi    String flushStatistics() throws Exception {
4330699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi        IpConnectivityMetrics metricsService =
4340699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi                new IpConnectivityMetrics(mock(Context.class), (ctx) -> 2000);
4350699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi        metricsService.mNetdListener = mNetdEventListenerService;
4360699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi
4370699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi        StringWriter buffer = new StringWriter();
4380699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi        PrintWriter writer = new PrintWriter(buffer);
4390699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi        metricsService.impl.dump(null, writer, new String[]{"flush"});
4400699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi        byte[] bytes = Base64.decode(buffer.toString(), Base64.DEFAULT);
441dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi        IpConnectivityLog log = IpConnectivityLog.parseFrom(bytes);
442dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi        for (IpConnectivityEvent ev : log.events) {
443dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi            if (ev.getConnectStatistics() == null) {
444dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                continue;
445dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi            }
446dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi            // Sort repeated fields of connect() events arriving in non-deterministic order.
447dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi            Arrays.sort(ev.getConnectStatistics().latenciesMs);
448dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi            Arrays.sort(ev.getConnectStatistics().errnosCounters,
449dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi                    Comparator.comparingInt((p) -> p.key));
450dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi        }
451dfc2cc5857199345e08f07977b79b20292f964a2Hugo Benichi        return log.toString();
4520699cf98042a64e41ee076c464eb115a6579be08Hugo Benichi    }
4531e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi
4541e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi    String[] listNetdEvent() throws Exception {
4551e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi        StringWriter buffer = new StringWriter();
4561e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi        PrintWriter writer = new PrintWriter(buffer);
4571e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi        mNetdEventListenerService.list(writer);
4581e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi        return buffer.toString().split("\\n");
4591e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi    }
4601e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi
4611e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi    static void assertContains(String got, String want) {
4621e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi        assertTrue(got + " did not contain \"" + want + "\"", got.contains(want));
4631e327edae342b7d0060ca61c98c95cf1fee0b0cdHugo Benichi    }
4645e055187bea4f4c96799a3e7fcc5aaaf57740ea3Hugo Benichi}
465