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