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