1# 2# Copyright 2019 - 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 16import random 17import re 18import time 19from acts import asserts 20from acts import base_test 21from acts.test_decorators import test_tracker_info 22from acts.test_utils.net import connectivity_test_utils as cutils 23from acts.test_utils.net import net_test_utils as nutils 24from acts.test_utils.net import socket_test_utils as sutils 25from acts.test_utils.net.net_test_utils import start_tcpdump 26from acts.test_utils.net.net_test_utils import stop_tcpdump 27from acts.test_utils.wifi import wifi_test_utils as wutils 28from scapy.all import rdpcap 29from scapy.all import Scapy_Exception 30from scapy.all import TCP 31from scapy.all import UDP 32 33 34ACK = "A" 35DROPPED_IPV4_KA_ACK = "DROPPED_IPV4_KEEPALIVE_ACK" 36MIN_TEST_KA_INTERVAL = 10 37# max keepalive interval is kept to 60 for test purposes 38MAX_TEST_KA_INTERVAL = 60 39# sleep time to test keepalives. this is set to a prime number to prevent 40# race conditions and as a result flaky tests. 41# Ex: if keepalive is started with 42s time interval, we expect 4 keepalives 42# after 181s. 43SLEEP_TIME = 181 44STRESS_COUNT = 5 45SUPPORTED_KERNEL_VERSION = 4.8 46TCP_SERVER_PORT = 853 47UDP_SERVER_PORT = 4500 48 49 50class SocketKeepaliveTest(base_test.BaseTestClass): 51 """Tests for Socket keepalive.""" 52 53 def __init__(self, controllers): 54 """List and order of tests to run.""" 55 base_test.BaseTestClass.__init__(self, controllers) 56 self.tests = ( 57 "test_tcp_socket_keepalive_start_stop_wifi", 58 "test_natt_socket_keepalive_start_stop_wifi", 59 "test_tcp_socket_keepalive_error_client_socket_close_wifi", 60 "test_tcp_socket_keepalive_over_max_keepalive_limit_wifi", 61 "test_tcp_socket_keepalive_invalid_interval", 62 "test_natt_socket_keepalive_invalid_interval", 63 "test_tcp_socket_keepalive_start_stop_multiple_keepalives_wifi", 64 "test_tcp_socket_keepalive_start_stop_stress_wifi", 65 "test_tcp_socket_keepalive_on_data_received_wifi", 66 "test_natt_socket_keepalive_start_stop_lte",) 67 68 def setup_class(self): 69 """Setup devices for tests and unpack params.""" 70 71 self.dut = self.android_devices[1] 72 # remote_server_2 is the host machine to test OnDataCallback and Error 73 # callbacks. The server program sends data to the DUT while keepalive 74 # is enabled. It also closes the server socket to verify Error callback 75 # 'test_tcp_socket_keepalive_on_data_received_wifi' requires this. 76 # remote_server is the host machine to test all other test cases. 77 # This host listens, accepts connections and verifies the keepalive 78 # intervals. 79 req_params = ("wifi_network", "remote_server", "remote_server_2") 80 self.unpack_userparams(req_params) 81 nutils.verify_lte_data_and_tethering_supported(self.dut) 82 self.max_ka_net = self.dut.droid.getSupportedKeepalivesForNetwork() 83 self.log.info("Max Keepalives for mobile network: %s" % self.max_ka_net) 84 wutils.start_wifi_connection_scan_and_ensure_network_found( 85 self.dut, self.wifi_network["SSID"]) 86 wutils.wifi_connect(self.dut, self.wifi_network) 87 self.max_ka_wifi = self.dut.droid.getSupportedKeepalivesForNetwork() 88 self.log.info("Max Keepalives on wifi network: %s" % self.max_ka_wifi) 89 self.kernel_version = self._get_kernel_version(self.dut) 90 self.log.info("Kernel version: %s" % self.kernel_version) 91 92 self.host_ip = self.remote_server["ip_addr"] 93 self.tcpdump_pid = None 94 self.tcp_sockets = [] 95 self.socket_keepalives = [] 96 self.gce_tcpdump_pid = None 97 self.udp_encap = None 98 99 def setup_test(self): 100 asserts.skip_if( 101 self.test_name.startswith("test_tcp") and \ 102 self.kernel_version < SUPPORTED_KERNEL_VERSION, 103 "TCP Keepalive is not supported on kernel %s. Need at least %s" % 104 (self.kernel_version, SUPPORTED_KERNEL_VERSION)) 105 106 if self.test_name.endswith("_lte"): 107 wutils.wifi_toggle_state(self.dut, False) 108 time.sleep(3) 109 link_prop = self.dut.droid.connectivityGetActiveLinkProperties() 110 iface = link_prop["InterfaceName"] 111 self.log.info("Iface: %s" % iface) 112 self.dut_ip = self.dut.droid.connectivityGetIPv4Addresses(iface)[0] 113 self.tcpdump_pid = start_tcpdump(self.dut, self.test_name) 114 115 def teardown_test(self): 116 if self.tcpdump_pid: 117 stop_tcpdump(self.dut, self.tcpdump_pid, self.test_name) 118 self.tcpdump_pid = None 119 if self.gce_tcpdump_pid: 120 host = self.remote_server 121 if "_on_data_" in self.test_name: 122 host = self.remote_server_2 123 nutils.stop_tcpdump_gce_server( 124 self.dut, self.gce_tcpdump_pid, None, host) 125 self.gce_tcpdump_pid = None 126 for ska in self.socket_keepalives: 127 cutils.stop_socket_keepalive(self.dut, ska) 128 self.socket_keepalives = [] 129 for sock in self.tcp_sockets: 130 sutils.shutdown_socket(self.dut, sock) 131 self.tcp_sockets = [] 132 if self.udp_encap: 133 self.dut.droid.ipSecCloseUdpEncapsulationSocket(self.udp_encap) 134 self.udp_encap = None 135 wutils.wifi_toggle_state(self.dut, True) 136 137 def teardown_class(self): 138 wutils.reset_wifi(self.dut) 139 140 def on_fail(self, test_name, begin_time): 141 self.dut.take_bug_report(test_name, begin_time) 142 143 ### Helper functions 144 145 def _get_kernel_version(self, ad): 146 """Get the kernel version on the device. 147 148 Args: 149 ad: android device object. 150 151 Returns: 152 Kernel version on the device. 153 """ 154 cmd_out = ad.adb.shell("cat /proc/version") 155 pattern_match = re.findall(r"^Linux version \d.\d", cmd_out) 156 return float(pattern_match[0].split()[-1]) if pattern_match else None 157 158 def _verify_tcp_keepalives(self, 159 pcap, 160 interval, 161 cport, 162 beg, 163 end, 164 expected_ka_count, 165 verify_ka_interval=True): 166 """Verify TCP keepalives received by host. 167 168 Args: 169 pcap: tcpdump file from host. 170 interval: keepalive time interval. 171 cport: client port after NAT on the host. 172 beg: beginning time for keepalives. 173 end: end time for keepalives. 174 expected_ka_count: expected no. of KA packets. 175 verify_ka_interval: if true, verify the keepalive time interval. 176 177 Returns: 178 True/False if keepalives are successful. 179 """ 180 try: 181 packets = rdpcap(pcap) 182 except Scapy_Exception: 183 asserts.fail("Not a valid pcap file") 184 185 seq = None 186 time_stamps = [] 187 for pkt in packets: 188 if pkt.time < beg: 189 continue 190 if pkt.time > end: 191 break 192 if TCP in pkt and pkt[TCP].dport == TCP_SERVER_PORT and \ 193 pkt[TCP].sport == cport and pkt[TCP].flags == ACK and \ 194 not seq or pkt[TCP].seq == seq: 195 196 seq = pkt[TCP].seq 197 time_stamps.append(pkt.time) 198 199 self.log.info("KA count: %s, expected %s" % (len(time_stamps), 200 expected_ka_count)) 201 if len(time_stamps) != expected_ka_count: 202 return False 203 if not verify_ka_interval: 204 return True 205 return self._verify_keepalive_interval(time_stamps, interval) 206 207 def _verify_natt_keepalives(self, 208 pcap, 209 interval, 210 beg, 211 end, 212 expected_ka_count): 213 """Verify Natt keepalives received by host. 214 215 Args: 216 pcap: tcpdump file from host. 217 interval: expected time difference between keepalives. 218 beg: beginning time for keepalives. 219 end: end time for keepalives. 220 expected_ka_count: expected keepalive count. 221 222 Returns: 223 True/False if keepalives are successful. 224 """ 225 try: 226 packets = rdpcap(pcap) 227 except Scapy_Exception: 228 asserts.fail("Not a valid pcap file") 229 230 ka_dict = {} 231 for pkt in packets: 232 if pkt.time < beg: 233 continue 234 if pkt.time > end: 235 break 236 if UDP in pkt and pkt[UDP].dport == UDP_SERVER_PORT: 237 if pkt[UDP].sport not in ka_dict: 238 ka_dict[pkt[UDP].sport] = [float(pkt.time)] 239 else: 240 ka_dict[pkt[UDP].sport].append(float(pkt.time)) 241 242 for sport in ka_dict: 243 self.log.info("Source port: %s" % sport) 244 self.log.info("KA count: %s, expected: %s" % (len(ka_dict[sport]), 245 expected_ka_count)) 246 if len(ka_dict[sport]) == expected_ka_count and \ 247 self._verify_keepalive_interval(ka_dict[sport], interval): 248 return True 249 self.log.error("Keepalive time interval verification failed") 250 return False 251 252 def _verify_keepalive_interval(self, time_stamps, interval): 253 """Verify time difference between keepalive packets. 254 255 Args: 256 time_stamps: List of timestamps of each keepalive. 257 interval: Expected time difference. 258 259 Returns: 260 True if Keepalive interval matches with expected value. 261 """ 262 i = 0 263 for t in time_stamps: 264 if i == 0: 265 prev = t 266 i += 1 267 continue 268 diff = int(round(t - prev)) 269 self.log.info("KA interval: %s, expected: %s" % (diff, interval)) 270 if diff != interval: 271 return False 272 prev = t 273 i += 1 274 return True 275 276 def _get_expected_ka_count(self, elapsed_time, ka_time_interval): 277 """Get expected keepalive count. 278 279 Args: 280 elapsed_time: time in seconds within which to count the keepalives. 281 ka_time_interval: time interval between keepalives. 282 283 Returns: 284 no. of keepalives. 285 """ 286 return int(elapsed_time/ka_time_interval) 287 288 def _get_client_port_and_time_interval(self): 289 """Generate a random tcp port and keepalive time interval. 290 291 Returns: 292 client_port and keepalive time interval. 293 """ 294 # (TODO: @gmoturu) Change this to autobind instead of generating a port. 295 client_port = random.randint(8000, 9000) 296 time_interval = random.randint(MIN_TEST_KA_INTERVAL, 297 MAX_TEST_KA_INTERVAL) 298 self.log.info("Socket Keepalive time interval: %s" % time_interval) 299 return client_port, time_interval 300 301 def _open_tcp_socket_and_connect(self, client_port, server_ip=None): 302 """Open a TCP socket and connect to server for keepalive testing. 303 304 Args: 305 client_port: port to open tcp socket on. 306 server_ip: IP addr of remote server. 307 308 Returns: 309 socket object and client port seen by server. 310 """ 311 if not server_ip: 312 server_ip = self.host_ip 313 sock = self.dut.droid.openTcpSocket(server_ip, 314 TCP_SERVER_PORT, 315 self.dut_ip, 316 client_port) 317 asserts.assert_true(sock, "Failed to open TCP socket") 318 self.log.info("Socket key: %s" % sock) 319 self.tcp_sockets.append(sock) 320 cport_server = self.dut.droid.tcpSocketRecv(sock) 321 asserts.assert_true(cport_server, "Received null message from server") 322 self.log.info("Client port after NAT on host: %s" % cport_server) 323 return sock, cport_server 324 325 def _start_tcp_keepalive(self, sock, time_interval, expect_ka_start=True): 326 """Start TCP keepalive. 327 328 Args: 329 sock: TCP socket object. 330 time_interval: keepalive time interval. 331 expect_ka_start: if True, KA should Start, else Error outcome. 332 333 Returns: 334 key of socket keepalive object. 335 """ 336 ska_key = cutils.start_tcp_socket_keepalive(self.dut, 337 sock, 338 time_interval) 339 340 if not expect_ka_start: 341 asserts.assert_false(ska_key, 342 "Expected starting socket keepalive to fail") 343 return None 344 345 asserts.assert_true(ska_key, "Failed to start socket keepalive") 346 self.socket_keepalives.append(ska_key) 347 return ska_key 348 349 def _get_dropped_keepalive_acks(self, ack=DROPPED_IPV4_KA_ACK): 350 """Get dropped keepalive acks from dumpsys output. 351 352 Args: 353 ack: Type of keepalive ack to check. 354 355 Returns: 356 Number of dropped acks. 357 """ 358 dropped_acks = self.dut.adb.shell( 359 "dumpsys network_stack | grep '%s'" % ack) 360 dropped_acks = dropped_acks.rstrip() 361 self.log.info("Dropped keepalive acks: %s" % dropped_acks) 362 return 0 if not dropped_acks else int(dropped_acks.split(":")[-1]) 363 364 def _test_socket_keepalive_start_stop(self): 365 """Test NATT and TCP socket keepalives for wifi and mobile networks.""" 366 tcp_keepalive = True if "_tcp_" in self.test_name else False 367 ad = self.dut 368 port = TCP_SERVER_PORT if tcp_keepalive else UDP_SERVER_PORT 369 self.log.info("Client IP: %s" % self.dut_ip) 370 self.log.info("Server IP: %s" % self.host_ip) 371 372 # start tcpdump on the server 373 self.gce_tcpdump_pid, pcap_path = nutils.start_tcpdump_gce_server( 374 ad, self.test_name, port, self.remote_server) 375 376 # start keepalive 377 client_port, time_interval = self._get_client_port_and_time_interval() 378 ska_key = None 379 if tcp_keepalive: 380 self.log.info("Client port: %s" % client_port) 381 self.log.info("Server port: %s" % TCP_SERVER_PORT) 382 sock, cport_server = self._open_tcp_socket_and_connect(client_port) 383 ska_key = self._start_tcp_keepalive(sock, time_interval) 384 else: 385 self.log.info("UDP encap port on server: %s" % UDP_SERVER_PORT) 386 self.udp_encap = self.dut.droid.ipSecOpenUdpEncapsulationSocket() 387 ska_key = cutils.start_natt_socket_keepalive(self.dut, 388 self.udp_encap, 389 self.dut_ip, 390 self.host_ip, 391 time_interval) 392 self.socket_keepalives.append(ska_key) 393 asserts.assert_true(ska_key, "Failed to start socket keepalive") 394 395 # sleep for sometime to verify keepalives 396 beg_time = time.time() 397 self.log.info("Sleeping for %s seconds" % SLEEP_TIME) 398 time.sleep(SLEEP_TIME) 399 end_time = time.time() 400 401 # stop tcpdump 402 pcap_file = nutils.stop_tcpdump_gce_server( 403 ad, self.gce_tcpdump_pid, pcap_path, self.remote_server) 404 self.gce_tcpdump_pid = None 405 406 # verify keepalives 407 expected_ka_count = self._get_expected_ka_count(end_time-beg_time, 408 time_interval) 409 410 if tcp_keepalive: 411 result = self._verify_tcp_keepalives( 412 pcap_file, time_interval, int(cport_server), beg_time, end_time, 413 expected_ka_count) 414 else: 415 result = self._verify_natt_keepalives( 416 pcap_file, time_interval, beg_time, end_time, expected_ka_count) 417 asserts.assert_true(result, "Keepalive verification failed") 418 419 ### Tests begin 420 421 @test_tracker_info(uuid="537e13ef-2366-40a3-86d4-596266d21eda") 422 def test_tcp_socket_keepalive_start_stop_wifi(self): 423 """Test TCP keepalive for onStart and onStop callbacks. 424 425 Steps: 426 1. Open a TCP socket on DUT and connect to server. 427 2. Start TCP keepalive and verify onStarted callback is received. 428 3. Verify that server received the keepalives. 429 4. Stop TCP keepalive and verify onStopped callback is received. 430 """ 431 self._test_socket_keepalive_start_stop() 432 433 @test_tracker_info(uuid="8f23f3a0-7b65-4b5c-bc91-5decaddb7c9c") 434 def test_tcp_socket_keepalive_on_data_received_wifi(self): 435 """Test Error callback for tcp socket keepalive. 436 437 Steps: 438 1. Open a TCP socket on DUT and connect ot server on port 853. 439 2. Start TCP keepalive and verify on Start callback. 440 3. Send message from server and verify OnDataReceived Callback. 441 4. Send data and recv data from server. 442 5. Start keeaplive again and verify server receives them. 443 """ 444 # start tcpdump on the server 445 host = self.remote_server_2 446 host_ip = host["ip_addr"] 447 tcpdump_pid, pcap_path = nutils.start_tcpdump_gce_server( 448 self.dut, self.test_name, TCP_SERVER_PORT, host) 449 450 # open socket, connect to server, start keepalive 451 time_interval = 11 452 sleep_time = 37 453 keepalive_count = 3 454 self.log.info("Client IP: %s" % self.dut_ip) 455 self.log.info("Server IP: %s" % host_ip) 456 client_port = random.randint(8000, 9000) 457 self.log.info("Client port: %s" % client_port) 458 sock, cport_server = self._open_tcp_socket_and_connect(client_port, 459 host_ip) 460 ska_key = self._start_tcp_keepalive(sock, time_interval) 461 462 # wait for data to be received from server 463 begin_time = time.time() 464 self.log.info("Sleeping for %s seconds" % sleep_time) 465 time.sleep(sleep_time) 466 recv_msg = self.dut.droid.tcpSocketRecv(sock) 467 self.log.info("Received message: %s" % recv_msg) 468 469 # verify onDataReceived callback 470 status = cutils.socket_keepalive_data_received(self.dut, ska_key) 471 asserts.assert_true(status, "Failed to receive onDataReceived callback") 472 self.socket_keepalives = [] 473 474 # wait for some time before starting keepalives 475 self.log.info("Sleeping for %s seconds" % sleep_time) 476 time.sleep(sleep_time) 477 478 # re-start keepalives and sleep for sometime to verify keepalives 479 ska_key = self._start_tcp_keepalive(sock, time_interval) 480 self.log.info("Sleeping for %s seconds" % sleep_time) 481 time.sleep(sleep_time) 482 end_time = time.time() 483 dropped_acks = self._get_dropped_keepalive_acks() 484 485 # expected ka count here is not based on beg_time and end_time as we 486 # wait some time before re-starting keepalives after OnDataReceived 487 # callback. the elapsed time will be sleep_time * 2. the extra keepalive 488 # accounts for the one sent by kernel. b/132924144 for reference. 489 expected_ka_count = 1+self._get_expected_ka_count(sleep_time*2, 490 time_interval) 491 492 # stop tcpdump 493 pcap_file = nutils.stop_tcpdump_gce_server( 494 self.dut, tcpdump_pid, pcap_path, host) 495 496 # server closes socket - verify error callback 497 time.sleep(60) 498 status = cutils.socket_keepalive_error(self.dut, ska_key) 499 asserts.assert_true(status, "Failed to receive onError callback") 500 self.socket_keepalives = [] 501 self.tcp_sockets = [] 502 503 # verify keepalives 504 result = self._verify_tcp_keepalives(pcap_file, 505 time_interval, 506 int(cport_server), 507 begin_time, 508 end_time, 509 expected_ka_count, 510 False) 511 asserts.assert_true(result and keepalive_count == dropped_acks, 512 "Keepalive verification failed") 513 asserts.assert_true(result, "Keepalive verification failed") 514 515 @test_tracker_info(uuid="c02bcc1c-f86b-4905-973a-b4200a2b86c1") 516 def test_tcp_socket_keepalive_start_stop_multiple_keepalives_wifi(self): 517 """Test TCP keepalive for onStart and onStop callbacks. 518 519 Steps: 520 1. Open 3 TCP socket on DUT and connect to server. 521 2. Start TCP keepalive and verify onStarted callback is received. 522 3. Verify that server received the keepalives. 523 4. Stop TCP keepalive and verify onStopped callback is received. 524 """ 525 # start tcpdump on the server 526 tcpdump_pid, pcap_path = nutils.start_tcpdump_gce_server( 527 self.dut, self.test_name, TCP_SERVER_PORT, self.remote_server) 528 529 # open 3 sockets and start keepalives 530 interval_list = [] 531 cport_list = [] 532 cport_server_list = [] 533 self.log.info("Client IP: %s" % self.dut_ip) 534 self.log.info("Server IP: %s" % self.host_ip) 535 for _ in range(self.max_ka_wifi): 536 cport, interval = self._get_client_port_and_time_interval() 537 cport_list.append(cport) 538 interval_list.append(interval) 539 540 for _ in range(self.max_ka_wifi): 541 sock, cport_server = self._open_tcp_socket_and_connect( 542 cport_list[_]) 543 self._start_tcp_keepalive(sock, interval_list[_]) 544 cport_server_list.append(cport_server) 545 546 # sleep for sometime to verify keepalives 547 begin_time = time.time() 548 self.log.info("Sleeping for %s seconds" % SLEEP_TIME) 549 time.sleep(SLEEP_TIME) 550 end_time = time.time() 551 dropped_acks = self._get_dropped_keepalive_acks() 552 553 # stop tcpdump 554 pcap_file = nutils.stop_tcpdump_gce_server( 555 self.dut, tcpdump_pid, pcap_path, self.remote_server) 556 557 # verify keepalives 558 total_dropped_acks = 0 559 for _ in range(self.max_ka_wifi): 560 total_dropped_acks += int(SLEEP_TIME/interval_list[_]) 561 expected_ka_count = self._get_expected_ka_count(end_time-begin_time, 562 interval_list[_]) 563 result = self._verify_tcp_keepalives(pcap_file, 564 interval_list[_], 565 int(cport_server_list[_]), 566 begin_time, 567 end_time, 568 expected_ka_count) 569 asserts.assert_true(result, "Keepalive verification failed") 570 571 @test_tracker_info(uuid="64374896-7a04-4a5b-b27c-e27b5f0e7159") 572 def test_tcp_socket_keepalive_start_stop_stress_wifi(self): 573 """Test TCP keepalive for onStart and onStop callbacks. 574 575 Steps: 576 1. Open 3 TCP socket on DUT and connect to server. 577 2. Start TCP keepalive and verify onStarted callback is received. 578 3. Verify that server received the keepalives. 579 4. Stop TCP keepalive and verify onStopped callback is received. 580 5. Repeat steps 1-4 few times. 581 """ 582 # open 3 sockets 583 interval_list = [] 584 cport_server_list = [] 585 sock_list = [] 586 587 self.log.info("Client IP: %s" % self.dut_ip) 588 self.log.info("Server IP: %s" % self.host_ip) 589 for _ in range(self.max_ka_wifi): 590 client_port = random.randint(8000, 9000) 591 self.log.info("Client port: %s" % client_port) 592 sock, cport_server = self._open_tcp_socket_and_connect(client_port) 593 sock_list.append(sock) 594 cport_server_list.append(cport_server) 595 596 for _ in range(STRESS_COUNT): 597 598 # start tcpdump on the server 599 tcpdump_pid, pcap_path = nutils.start_tcpdump_gce_server( 600 self.dut, self.test_name, TCP_SERVER_PORT, self.remote_server) 601 602 # start keepalives on sockets 603 for _ in range(self.max_ka_wifi): 604 time_interval = random.randint(MIN_TEST_KA_INTERVAL, 605 MAX_TEST_KA_INTERVAL) 606 self.log.info("TCP socket Keepalive time interval: %s" % 607 time_interval) 608 interval_list.append(time_interval) 609 self._start_tcp_keepalive(sock_list[_], interval_list[_]) 610 611 # sleep for sometime to verify keepalives 612 begin_time = time.time() 613 self.log.info("Sleeping for %s seconds" % SLEEP_TIME) 614 time.sleep(SLEEP_TIME) 615 end_time = time.time() 616 dropped_acks = self._get_dropped_keepalive_acks() 617 618 # stop keepalives 619 for ska in self.socket_keepalives: 620 self.log.info("Stopping keepalive %s" % ska) 621 cutils.stop_socket_keepalive(self.dut, ska) 622 self.socket_keepalives = [] 623 624 # stop tcpdump 625 pcap_file = nutils.stop_tcpdump_gce_server( 626 self.dut, tcpdump_pid, pcap_path, self.remote_server) 627 628 # verify keepalives 629 total_dropped_acks = 0 630 for _ in range(self.max_ka_wifi): 631 total_dropped_acks += int(SLEEP_TIME/interval_list[_]) 632 expected_ka_count = self._get_expected_ka_count( 633 end_time-begin_time, interval_list[_]) 634 result = self._verify_tcp_keepalives(pcap_file, 635 interval_list[_], 636 int(cport_server_list[_]), 637 begin_time, 638 end_time, 639 expected_ka_count) 640 asserts.assert_true(result, "Keepalive verification failed") 641 642 interval_list = [] 643 644 @test_tracker_info(uuid="de3970c1-23d1-4d52-b3c9-4a2f1e53e7f6") 645 def test_tcp_socket_keepalive_error_client_socket_close_wifi(self): 646 """Test Error callback for tcp socket keepalive. 647 648 Steps: 649 1. Open a TCP socket on DUT and connect to server on port 853. 650 2. Start TCP keepalive and verify on Start callback. 651 3. Wait for some time and shutdown the client socket. 652 4. Verify on Error callback is received. 653 """ 654 # open socket, connect to server, start keepalive 655 client_port, time_interval = self._get_client_port_and_time_interval() 656 sock, _ = self._open_tcp_socket_and_connect(client_port) 657 ska_key = self._start_tcp_keepalive(sock, time_interval) 658 659 # wait for atleast 1 keepalive 660 self.log.info("Sleeping for %s seconds" % (time_interval+1)) 661 time.sleep(time_interval+1) 662 663 # shutdown client socket 664 sutils.shutdown_socket(self.dut, sock) 665 self.tcp_sockets.remove(sock) 666 self.socket_keepalives = [] 667 668 # verify Error callback received 669 result = cutils.socket_keepalive_error(self.dut, ska_key) 670 asserts.assert_true(result, "Failed to receive error callback") 671 672 @test_tracker_info(uuid="7c902e51-725a-41f1-aebc-8528197c450c") 673 def test_tcp_socket_keepalive_over_max_keepalive_limit_wifi(self): 674 """Test TCP socket keepalive over max keepalive limit. 675 676 Steps: 677 1. Start 4 TCP socket keepalives. 678 2. 3 Should be successful and 4th should fail with Error. 679 """ 680 # open sockets and connect to server 681 max_ka_net = self.dut.droid.getSupportedKeepalivesForNetwork() 682 self.log.info("Max Keepalives supported: %s" % max_ka_net) 683 state = True 684 for _ in range(1, max_ka_net+1): 685 cport, interval = self._get_client_port_and_time_interval() 686 sock, _ = self._open_tcp_socket_and_connect(cport) 687 if _ == max_ka_net: 688 state = False 689 self._start_tcp_keepalive(sock, interval, state) 690 691 @test_tracker_info(uuid="308004c5-8e40-4e8b-9408-4a90e85a2261") 692 def test_tcp_socket_keepalive_invalid_interval(self): 693 """Test TCP socket keepalive with invalid interval. 694 695 Steps: 696 1. Start TCP socket keepalive with time interval <10 seconds. 697 2. Verify Error callback is received. 698 """ 699 # keepalive time interval, client port 700 client_port = random.randint(8000, 9000) 701 time_interval = random.randint(1, 9) 702 self.log.info("Client port: %s" % client_port) 703 self.log.info("Server port: %s" % TCP_SERVER_PORT) 704 705 # open tcp socket 706 sock, _ = self._open_tcp_socket_and_connect(client_port) 707 708 # start TCP socket keepalive 709 self.log.info("TCP socket Keepalive time interval: %s" % time_interval) 710 self._start_tcp_keepalive(sock, time_interval, False) 711 712 @test_tracker_info(uuid="c9012da2-656f-44ef-bad6-26892335d4bd") 713 def test_natt_socket_keepalive_start_stop_wifi(self): 714 """Test Natt socket keepalive for onStart and onStop callbacks. 715 716 Steps: 717 1. Open a UDP encap socket on DUT. 718 2. Start Natt socket keepalive. 719 3. Verify that server received the keepalives. 720 4. Stop keepalive and verify onStopped callback is received. 721 """ 722 self._test_socket_keepalive_start_stop() 723 724 @test_tracker_info(uuid="646bfd5d-936f-4069-8dea-fdd02582550d") 725 def test_natt_socket_keepalive_start_stop_lte(self): 726 """Test Natt socket keepalive for onStart and onStop callbacks. 727 728 Steps: 729 1. Open a UDP encap socket on DUT. 730 2. Start Natt socket keepalive. 731 3. Verify that server received the keepalives. 732 4. Stop keepalive and verify onStopped callback is received. 733 """ 734 self._test_socket_keepalive_start_stop() 735 736 @test_tracker_info(uuid="8ab20733-4a9e-4e4d-a46f-4d32a9f221c5") 737 def test_natt_socket_keepalive_invalid_interval(self): 738 """Test invalid natt socket keepalive time interval. 739 740 Steps: 741 1. Start NATT socket keepalive with time interval <10 seconds. 742 2. Verify Error callback is recevied. 743 """ 744 # keepalive time interval, client port 745 time_interval = random.randint(1, 9) 746 self.log.info("Natt socket keepalive time interval: %s" % time_interval) 747 self.log.info("UDP encap port on server: %s" % UDP_SERVER_PORT) 748 749 # open udp encap socket 750 self.udp_encap = self.dut.droid.ipSecOpenUdpEncapsulationSocket() 751 752 # start Natt socket keepalive 753 ska_key = cutils.start_natt_socket_keepalive( 754 self.dut, self.udp_encap, self.dut_ip, self.host_ip, time_interval) 755 asserts.assert_true(not ska_key, "Failed to receive error callback") 756 757 ### Tests End 758