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