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 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
     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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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 
    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 
    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