• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.android.server.connectivity;
18 
19 import static android.net.metrics.INetdEventListener.EVENT_GETADDRINFO;
20 import static android.net.metrics.INetdEventListener.EVENT_GETHOSTBYNAME;
21 import static com.android.server.connectivity.MetricsTestUtil.aBool;
22 import static com.android.server.connectivity.MetricsTestUtil.aByteArray;
23 import static com.android.server.connectivity.MetricsTestUtil.aLong;
24 import static com.android.server.connectivity.MetricsTestUtil.aString;
25 import static com.android.server.connectivity.MetricsTestUtil.aType;
26 import static com.android.server.connectivity.MetricsTestUtil.anInt;
27 import static com.android.server.connectivity.MetricsTestUtil.anIntArray;
28 import static com.android.server.connectivity.MetricsTestUtil.b;
29 import static com.android.server.connectivity.MetricsTestUtil.describeIpEvent;
30 import static com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityLog;
31 import static com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.BLUETOOTH;
32 import static com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.CELLULAR;
33 import static com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.ETHERNET;
34 import static com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.MULTIPLE;
35 import static com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.WIFI;
36 import static org.junit.Assert.assertEquals;
37 import static org.junit.Assert.fail;
38 
39 import android.net.ConnectivityMetricsEvent;
40 import android.net.metrics.ApfProgramEvent;
41 import android.net.metrics.ApfStats;
42 import android.net.metrics.ConnectStats;
43 import android.net.metrics.DefaultNetworkEvent;
44 import android.net.metrics.DhcpClientEvent;
45 import android.net.metrics.DhcpErrorEvent;
46 import android.net.metrics.DnsEvent;
47 import android.net.metrics.DnsEvent;
48 import android.net.metrics.IpManagerEvent;
49 import android.net.metrics.IpReachabilityEvent;
50 import android.net.metrics.NetworkEvent;
51 import android.net.metrics.RaEvent;
52 import android.net.metrics.ValidationProbeEvent;
53 import android.net.metrics.WakeupStats;
54 import android.support.test.runner.AndroidJUnit4;
55 import android.test.suitebuilder.annotation.SmallTest;
56 
57 import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityEvent;
58 
59 import java.util.Arrays;
60 import java.util.List;
61 
62 import org.junit.runner.RunWith;
63 import org.junit.Test;
64 
65 // TODO: instead of comparing textpb to textpb, parse textpb and compare proto to proto.
66 @RunWith(AndroidJUnit4.class)
67 @SmallTest
68 public class IpConnectivityEventBuilderTest {
69 
70     @Test
testLinkLayerInferrence()71     public void testLinkLayerInferrence() {
72         ConnectivityMetricsEvent ev = describeIpEvent(
73                 aType(IpReachabilityEvent.class),
74                 anInt(IpReachabilityEvent.NUD_FAILED));
75 
76         String want = String.join("\n",
77                 "dropped_events: 0",
78                 "events <",
79                 "  if_name: \"\"",
80                 "  link_layer: 0",
81                 "  network_id: 0",
82                 "  time_ms: 1",
83                 "  transports: 0",
84                 "  ip_reachability_event <",
85                 "    event_type: 512",
86                 "    if_name: \"\"",
87                 "  >",
88                 ">",
89                 "version: 2\n");
90         verifySerialization(want, ev);
91 
92         ev.netId = 123;
93         ev.transports = 3; // transports have priority for inferrence of link layer
94         ev.ifname = "wlan0";
95         want = String.join("\n",
96                 "dropped_events: 0",
97                 "events <",
98                 "  if_name: \"\"",
99                 String.format("  link_layer: %d", MULTIPLE),
100                 "  network_id: 123",
101                 "  time_ms: 1",
102                 "  transports: 3",
103                 "  ip_reachability_event <",
104                 "    event_type: 512",
105                 "    if_name: \"\"",
106                 "  >",
107                 ">",
108                 "version: 2\n");
109         verifySerialization(want, ev);
110 
111         ev.transports = 1;
112         ev.ifname = null;
113         want = String.join("\n",
114                 "dropped_events: 0",
115                 "events <",
116                 "  if_name: \"\"",
117                 String.format("  link_layer: %d", CELLULAR),
118                 "  network_id: 123",
119                 "  time_ms: 1",
120                 "  transports: 1",
121                 "  ip_reachability_event <",
122                 "    event_type: 512",
123                 "    if_name: \"\"",
124                 "  >",
125                 ">",
126                 "version: 2\n");
127         verifySerialization(want, ev);
128 
129         ev.transports = 0;
130         ev.ifname = "not_inferred";
131         want = String.join("\n",
132                 "dropped_events: 0",
133                 "events <",
134                 "  if_name: \"not_inferred\"",
135                 "  link_layer: 0",
136                 "  network_id: 123",
137                 "  time_ms: 1",
138                 "  transports: 0",
139                 "  ip_reachability_event <",
140                 "    event_type: 512",
141                 "    if_name: \"\"",
142                 "  >",
143                 ">",
144                 "version: 2\n");
145         verifySerialization(want, ev);
146 
147         ev.ifname = "bt-pan";
148         want = String.join("\n",
149                 "dropped_events: 0",
150                 "events <",
151                 "  if_name: \"\"",
152                 String.format("  link_layer: %d", BLUETOOTH),
153                 "  network_id: 123",
154                 "  time_ms: 1",
155                 "  transports: 0",
156                 "  ip_reachability_event <",
157                 "    event_type: 512",
158                 "    if_name: \"\"",
159                 "  >",
160                 ">",
161                 "version: 2\n");
162         verifySerialization(want, ev);
163 
164         ev.ifname = "rmnet_ipa0";
165         want = String.join("\n",
166                 "dropped_events: 0",
167                 "events <",
168                 "  if_name: \"\"",
169                 String.format("  link_layer: %d", CELLULAR),
170                 "  network_id: 123",
171                 "  time_ms: 1",
172                 "  transports: 0",
173                 "  ip_reachability_event <",
174                 "    event_type: 512",
175                 "    if_name: \"\"",
176                 "  >",
177                 ">",
178                 "version: 2\n");
179         verifySerialization(want, ev);
180 
181         ev.ifname = "wlan0";
182         want = String.join("\n",
183                 "dropped_events: 0",
184                 "events <",
185                 "  if_name: \"\"",
186                 String.format("  link_layer: %d", WIFI),
187                 "  network_id: 123",
188                 "  time_ms: 1",
189                 "  transports: 0",
190                 "  ip_reachability_event <",
191                 "    event_type: 512",
192                 "    if_name: \"\"",
193                 "  >",
194                 ">",
195                 "version: 2\n");
196         verifySerialization(want, ev);
197     }
198 
199     @Test
testDefaultNetworkEventSerialization()200     public void testDefaultNetworkEventSerialization() {
201         DefaultNetworkEvent ev = new DefaultNetworkEvent(1001);
202         ev.netId = 102;
203         ev.transports = 2;
204         ev.previousTransports = 4;
205         ev.ipv4 = true;
206         ev.initialScore = 20;
207         ev.finalScore = 60;
208         ev.durationMs = 54;
209         ev.validatedMs = 27;
210 
211         String want = String.join("\n",
212                 "dropped_events: 0",
213                 "events <",
214                 "  if_name: \"\"",
215                 "  link_layer: 4",
216                 "  network_id: 102",
217                 "  time_ms: 0",
218                 "  transports: 2",
219                 "  default_network_event <",
220                 "    default_network_duration_ms: 54",
221                 "    final_score: 60",
222                 "    initial_score: 20",
223                 "    ip_support: 1",
224                 "    no_default_network_duration_ms: 0",
225                 "    previous_default_network_link_layer: 1",
226                 "    previous_network_ip_support: 0",
227                 "    validation_duration_ms: 27",
228                 "  >",
229                 ">",
230                 "version: 2\n");
231 
232         verifySerialization(want, IpConnectivityEventBuilder.toProto(ev));
233     }
234 
235     @Test
testDhcpClientEventSerialization()236     public void testDhcpClientEventSerialization() {
237         ConnectivityMetricsEvent ev = describeIpEvent(
238                 aType(DhcpClientEvent.class),
239                 aString("SomeState"),
240                 anInt(192));
241 
242         String want = String.join("\n",
243                 "dropped_events: 0",
244                 "events <",
245                 "  if_name: \"\"",
246                 "  link_layer: 0",
247                 "  network_id: 0",
248                 "  time_ms: 1",
249                 "  transports: 0",
250                 "  dhcp_event <",
251                 "    duration_ms: 192",
252                 "    if_name: \"\"",
253                 "    state_transition: \"SomeState\"",
254                 "  >",
255                 ">",
256                 "version: 2\n");
257 
258         verifySerialization(want, ev);
259     }
260 
261     @Test
testDhcpErrorEventSerialization()262     public void testDhcpErrorEventSerialization() {
263         ConnectivityMetricsEvent ev = describeIpEvent(
264                 aType(DhcpErrorEvent.class),
265                 anInt(DhcpErrorEvent.L4_NOT_UDP));
266 
267         String want = String.join("\n",
268                 "dropped_events: 0",
269                 "events <",
270                 "  if_name: \"\"",
271                 "  link_layer: 0",
272                 "  network_id: 0",
273                 "  time_ms: 1",
274                 "  transports: 0",
275                 "  dhcp_event <",
276                 "    duration_ms: 0",
277                 "    if_name: \"\"",
278                 "    error_code: 50397184",
279                 "  >",
280                 ">",
281                 "version: 2\n");
282 
283         verifySerialization(want, ev);
284     }
285 
286     @Test
testIpManagerEventSerialization()287     public void testIpManagerEventSerialization() {
288         ConnectivityMetricsEvent ev = describeIpEvent(
289                 aType(IpManagerEvent.class),
290                 anInt(IpManagerEvent.PROVISIONING_OK),
291                 aLong(5678));
292 
293         String want = String.join("\n",
294                 "dropped_events: 0",
295                 "events <",
296                 "  if_name: \"\"",
297                 "  link_layer: 0",
298                 "  network_id: 0",
299                 "  time_ms: 1",
300                 "  transports: 0",
301                 "  ip_provisioning_event <",
302                 "    event_type: 1",
303                 "    if_name: \"\"",
304                 "    latency_ms: 5678",
305                 "  >",
306                 ">",
307                 "version: 2\n");
308 
309         verifySerialization(want, ev);
310     }
311 
312     @Test
testIpReachabilityEventSerialization()313     public void testIpReachabilityEventSerialization() {
314         ConnectivityMetricsEvent ev = describeIpEvent(
315                 aType(IpReachabilityEvent.class),
316                 anInt(IpReachabilityEvent.NUD_FAILED));
317 
318         String want = String.join("\n",
319                 "dropped_events: 0",
320                 "events <",
321                 "  if_name: \"\"",
322                 "  link_layer: 0",
323                 "  network_id: 0",
324                 "  time_ms: 1",
325                 "  transports: 0",
326                 "  ip_reachability_event <",
327                 "    event_type: 512",
328                 "    if_name: \"\"",
329                 "  >",
330                 ">",
331                 "version: 2\n");
332 
333         verifySerialization(want, ev);
334     }
335 
336     @Test
testNetworkEventSerialization()337     public void testNetworkEventSerialization() {
338         ConnectivityMetricsEvent ev = describeIpEvent(
339                 aType(NetworkEvent.class),
340                 anInt(5),
341                 aLong(20410));
342 
343         String want = String.join("\n",
344                 "dropped_events: 0",
345                 "events <",
346                 "  if_name: \"\"",
347                 "  link_layer: 0",
348                 "  network_id: 0",
349                 "  time_ms: 1",
350                 "  transports: 0",
351                 "  network_event <",
352                 "    event_type: 5",
353                 "    latency_ms: 20410",
354                 "  >",
355                 ">",
356                 "version: 2\n");
357 
358         verifySerialization(want, ev);
359     }
360 
361     @Test
testValidationProbeEventSerialization()362     public void testValidationProbeEventSerialization() {
363         ConnectivityMetricsEvent ev = describeIpEvent(
364                 aType(ValidationProbeEvent.class),
365                 aLong(40730),
366                 anInt(ValidationProbeEvent.PROBE_HTTP),
367                 anInt(204));
368 
369         String want = String.join("\n",
370                 "dropped_events: 0",
371                 "events <",
372                 "  if_name: \"\"",
373                 "  link_layer: 0",
374                 "  network_id: 0",
375                 "  time_ms: 1",
376                 "  transports: 0",
377                 "  validation_probe_event <",
378                 "    latency_ms: 40730",
379                 "    probe_result: 204",
380                 "    probe_type: 1",
381                 "  >",
382                 ">",
383                 "version: 2\n");
384 
385         verifySerialization(want, ev);
386     }
387 
388     @Test
testApfProgramEventSerialization()389     public void testApfProgramEventSerialization() {
390         ConnectivityMetricsEvent ev = describeIpEvent(
391                 aType(ApfProgramEvent.class),
392                 aLong(200),
393                 aLong(18),
394                 anInt(7),
395                 anInt(9),
396                 anInt(2048),
397                 anInt(3));
398 
399         String want = String.join("\n",
400                 "dropped_events: 0",
401                 "events <",
402                 "  if_name: \"\"",
403                 "  link_layer: 0",
404                 "  network_id: 0",
405                 "  time_ms: 1",
406                 "  transports: 0",
407                 "  apf_program_event <",
408                 "    current_ras: 9",
409                 "    drop_multicast: true",
410                 "    effective_lifetime: 18",
411                 "    filtered_ras: 7",
412                 "    has_ipv4_addr: true",
413                 "    lifetime: 200",
414                 "    program_length: 2048",
415                 "  >",
416                 ">",
417                 "version: 2\n");
418 
419         verifySerialization(want, ev);
420     }
421 
422     @Test
testApfStatsSerialization()423     public void testApfStatsSerialization() {
424         ConnectivityMetricsEvent ev = describeIpEvent(
425                 aType(ApfStats.class),
426                 aLong(45000),
427                 anInt(10),
428                 anInt(2),
429                 anInt(2),
430                 anInt(1),
431                 anInt(2),
432                 anInt(4),
433                 anInt(7),
434                 anInt(3),
435                 anInt(2048));
436 
437         String want = String.join("\n",
438                 "dropped_events: 0",
439                 "events <",
440                 "  if_name: \"\"",
441                 "  link_layer: 0",
442                 "  network_id: 0",
443                 "  time_ms: 1",
444                 "  transports: 0",
445                 "  apf_statistics <",
446                 "    dropped_ras: 2",
447                 "    duration_ms: 45000",
448                 "    matching_ras: 2",
449                 "    max_program_size: 2048",
450                 "    parse_errors: 2",
451                 "    program_updates: 4",
452                 "    program_updates_all: 7",
453                 "    program_updates_allowing_multicast: 3",
454                 "    received_ras: 10",
455                 "    total_packet_dropped: 0",
456                 "    total_packet_processed: 0",
457                 "    zero_lifetime_ras: 1",
458                 "  >",
459                 ">",
460                 "version: 2\n");
461 
462         verifySerialization(want, ev);
463     }
464 
465     @Test
testRaEventSerialization()466     public void testRaEventSerialization() {
467         ConnectivityMetricsEvent ev = describeIpEvent(
468                 aType(RaEvent.class),
469                 aLong(2000),
470                 aLong(400),
471                 aLong(300),
472                 aLong(-1),
473                 aLong(1000),
474                 aLong(-1));
475 
476         String want = String.join("\n",
477                 "dropped_events: 0",
478                 "events <",
479                 "  if_name: \"\"",
480                 "  link_layer: 0",
481                 "  network_id: 0",
482                 "  time_ms: 1",
483                 "  transports: 0",
484                 "  ra_event <",
485                 "    dnssl_lifetime: -1",
486                 "    prefix_preferred_lifetime: 300",
487                 "    prefix_valid_lifetime: 400",
488                 "    rdnss_lifetime: 1000",
489                 "    route_info_lifetime: -1",
490                 "    router_lifetime: 2000",
491                 "  >",
492                 ">",
493                 "version: 2\n");
494 
495         verifySerialization(want, ev);
496     }
497 
498     @Test
testWakeupStatsSerialization()499     public void testWakeupStatsSerialization() {
500         WakeupStats stats = new WakeupStats("wlan0");
501         stats.totalWakeups = 14;
502         stats.applicationWakeups = 5;
503         stats.nonApplicationWakeups = 1;
504         stats.rootWakeups = 2;
505         stats.systemWakeups = 3;
506         stats.noUidWakeups = 3;
507         stats.l2UnicastCount = 5;
508         stats.l2MulticastCount = 1;
509         stats.l2BroadcastCount = 2;
510         stats.ethertypes.put(0x800, 3);
511         stats.ethertypes.put(0x86dd, 3);
512         stats.ipNextHeaders.put(6, 5);
513 
514 
515         IpConnectivityEvent got = IpConnectivityEventBuilder.toProto(stats);
516         String want = String.join("\n",
517                 "dropped_events: 0",
518                 "events <",
519                 "  if_name: \"\"",
520                 "  link_layer: 4",
521                 "  network_id: 0",
522                 "  time_ms: 0",
523                 "  transports: 0",
524                 "  wakeup_stats <",
525                 "    application_wakeups: 5",
526                 "    duration_sec: 0",
527                 "    ethertype_counts <",
528                 "      key: 2048",
529                 "      value: 3",
530                 "    >",
531                 "    ethertype_counts <",
532                 "      key: 34525",
533                 "      value: 3",
534                 "    >",
535                 "    ip_next_header_counts <",
536                 "      key: 6",
537                 "      value: 5",
538                 "    >",
539                 "    l2_broadcast_count: 2",
540                 "    l2_multicast_count: 1",
541                 "    l2_unicast_count: 5",
542                 "    no_uid_wakeups: 3",
543                 "    non_application_wakeups: 1",
544                 "    root_wakeups: 2",
545                 "    system_wakeups: 3",
546                 "    total_wakeups: 14",
547                 "  >",
548                 ">",
549                 "version: 2\n");
550 
551         verifySerialization(want, got);
552     }
553 
verifySerialization(String want, ConnectivityMetricsEvent... input)554     static void verifySerialization(String want, ConnectivityMetricsEvent... input) {
555         List<IpConnectivityEvent> protoInput =
556                 IpConnectivityEventBuilder.toProto(Arrays.asList(input));
557         verifySerialization(want, protoInput.toArray(new IpConnectivityEvent[0]));
558     }
559 
verifySerialization(String want, IpConnectivityEvent... input)560     static void verifySerialization(String want, IpConnectivityEvent... input) {
561         try {
562             byte[] got = IpConnectivityEventBuilder.serialize(0, Arrays.asList(input));
563             IpConnectivityLog log = IpConnectivityLog.parseFrom(got);
564             assertEquals(want, log.toString());
565         } catch (Exception e) {
566             fail(e.toString());
567         }
568     }
569 }
570