1 #!/usr/bin/python3.4 2 # 3 # Copyright 2017 - The Android Open Source Project 4 # 5 # Licensed under the Apache License, Version 2.0 (the "License"); 6 # you may not use this file except in compliance with the License. 7 # You may obtain a copy of the License at 8 # 9 # http://www.apache.org/licenses/LICENSE-2.0 10 # 11 # Unless required by applicable law or agreed to in writing, software 12 # distributed under the License is distributed on an "AS IS" BASIS, 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 # See the License for the specific language governing permissions and 15 # limitations under the License. 16 17 import string 18 import time 19 20 from acts import asserts 21 from acts.test_decorators import test_tracker_info 22 from acts.test_utils.wifi.aware import aware_const as aconsts 23 from acts.test_utils.wifi.aware import aware_test_utils as autils 24 from acts.test_utils.wifi.aware.AwareBaseTest import AwareBaseTest 25 26 27 class DiscoveryTest(AwareBaseTest): 28 """Set of tests for Wi-Fi Aware discovery.""" 29 30 # configuration parameters used by tests 31 PAYLOAD_SIZE_MIN = 0 32 PAYLOAD_SIZE_TYPICAL = 1 33 PAYLOAD_SIZE_MAX = 2 34 35 # message strings 36 query_msg = "How are you doing? " 37 response_msg = "Doing ok - thanks! - " 38 39 # message re-transmit counter (increases reliability in open-environment) 40 # Note: reliability of message transmission is tested elsewhere 41 msg_retx_count = 5 # hard-coded max value, internal API 42 43 def __init__(self, controllers): 44 AwareBaseTest.__init__(self, controllers) 45 46 def create_base_config(self, caps, is_publish, ptype, stype, payload_size, 47 ttl, term_ind_on, null_match): 48 """Create a base configuration based on input parameters. 49 50 Args: 51 caps: device capability dictionary 52 is_publish: True if a publish config, else False 53 ptype: unsolicited or solicited (used if is_publish is True) 54 stype: passive or active (used if is_publish is False) 55 payload_size: min, typical, max (PAYLOAD_SIZE_xx) 56 ttl: time-to-live configuration (0 - forever) 57 term_ind_on: is termination indication enabled 58 null_match: null-out the middle match filter 59 Returns: 60 publish discovery configuration object. 61 """ 62 config = {} 63 if is_publish: 64 config[aconsts.DISCOVERY_KEY_DISCOVERY_TYPE] = ptype 65 else: 66 config[aconsts.DISCOVERY_KEY_DISCOVERY_TYPE] = stype 67 config[aconsts.DISCOVERY_KEY_TTL] = ttl 68 config[aconsts.DISCOVERY_KEY_TERM_CB_ENABLED] = term_ind_on 69 if payload_size == self.PAYLOAD_SIZE_MIN: 70 config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = "a" 71 config[aconsts.DISCOVERY_KEY_SSI] = None 72 config[aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST] = [] 73 elif payload_size == self.PAYLOAD_SIZE_TYPICAL: 74 config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = "GoogleTestServiceX" 75 if is_publish: 76 config[aconsts.DISCOVERY_KEY_SSI] = string.ascii_letters 77 else: 78 config[aconsts.DISCOVERY_KEY_SSI] = string.ascii_letters[:: 79 -1] # reverse 80 config[aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST] = autils.encode_list( 81 [(10).to_bytes(1, byteorder="big"), "hello there string" 82 if not null_match else None, 83 bytes(range(40))]) 84 else: # PAYLOAD_SIZE_MAX 85 config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = "VeryLong" + "X" * ( 86 caps[aconsts.CAP_MAX_SERVICE_NAME_LEN] - 8) 87 config[aconsts.DISCOVERY_KEY_SSI] = ("P" if is_publish else "S") * caps[ 88 aconsts.CAP_MAX_SERVICE_SPECIFIC_INFO_LEN] 89 mf = autils.construct_max_match_filter( 90 caps[aconsts.CAP_MAX_MATCH_FILTER_LEN]) 91 if null_match: 92 mf[2] = None 93 config[aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST] = autils.encode_list(mf) 94 95 return config 96 97 def create_publish_config(self, caps, ptype, payload_size, ttl, term_ind_on, 98 null_match): 99 """Create a publish configuration based on input parameters. 100 101 Args: 102 caps: device capability dictionary 103 ptype: unsolicited or solicited 104 payload_size: min, typical, max (PAYLOAD_SIZE_xx) 105 ttl: time-to-live configuration (0 - forever) 106 term_ind_on: is termination indication enabled 107 null_match: null-out the middle match filter 108 Returns: 109 publish discovery configuration object. 110 """ 111 return self.create_base_config(caps, True, ptype, None, payload_size, ttl, 112 term_ind_on, null_match) 113 114 def create_subscribe_config(self, caps, stype, payload_size, ttl, term_ind_on, 115 null_match): 116 """Create a subscribe configuration based on input parameters. 117 118 Args: 119 caps: device capability dictionary 120 stype: passive or active 121 payload_size: min, typical, max (PAYLOAD_SIZE_xx) 122 ttl: time-to-live configuration (0 - forever) 123 term_ind_on: is termination indication enabled 124 null_match: null-out the middle match filter 125 Returns: 126 subscribe discovery configuration object. 127 """ 128 return self.create_base_config(caps, False, None, stype, payload_size, ttl, 129 term_ind_on, null_match) 130 131 def positive_discovery_test_utility(self, ptype, stype, payload_size): 132 """Utility which runs a positive discovery test: 133 - Discovery (publish/subscribe) with TTL=0 (non-self-terminating) 134 - Exchange messages 135 - Update publish/subscribe 136 - Terminate 137 138 Args: 139 ptype: Publish discovery type 140 stype: Subscribe discovery type 141 payload_size: One of PAYLOAD_SIZE_* constants - MIN, TYPICAL, MAX 142 """ 143 p_dut = self.android_devices[0] 144 p_dut.pretty_name = "Publisher" 145 s_dut = self.android_devices[1] 146 s_dut.pretty_name = "Subscriber" 147 148 # Publisher+Subscriber: attach and wait for confirmation 149 p_id = p_dut.droid.wifiAwareAttach(False) 150 autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED) 151 time.sleep(self.device_startup_offset) 152 s_id = s_dut.droid.wifiAwareAttach(False) 153 autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED) 154 155 # Publisher: start publish and wait for confirmation 156 p_config = self.create_publish_config( 157 p_dut.aware_capabilities, 158 ptype, 159 payload_size, 160 ttl=0, 161 term_ind_on=False, 162 null_match=False) 163 p_disc_id = p_dut.droid.wifiAwarePublish(p_id, p_config) 164 autils.wait_for_event(p_dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED) 165 166 # Subscriber: start subscribe and wait for confirmation 167 s_config = self.create_subscribe_config( 168 s_dut.aware_capabilities, 169 stype, 170 payload_size, 171 ttl=0, 172 term_ind_on=False, 173 null_match=True) 174 s_disc_id = s_dut.droid.wifiAwareSubscribe(s_id, s_config) 175 autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED) 176 177 # Subscriber: wait for service discovery 178 discovery_event = autils.wait_for_event( 179 s_dut, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) 180 peer_id_on_sub = discovery_event["data"][aconsts.SESSION_CB_KEY_PEER_ID] 181 182 # Subscriber: validate contents of discovery: 183 # - SSI: publisher's 184 # - Match filter: UNSOLICITED - publisher, SOLICITED - subscriber 185 autils.assert_equal_strings( 186 bytes(discovery_event["data"][ 187 aconsts.SESSION_CB_KEY_SERVICE_SPECIFIC_INFO]).decode("utf-8"), 188 p_config[aconsts.DISCOVERY_KEY_SSI], 189 "Discovery mismatch: service specific info (SSI)") 190 asserts.assert_equal( 191 autils.decode_list( 192 discovery_event["data"][aconsts.SESSION_CB_KEY_MATCH_FILTER_LIST]), 193 autils.decode_list(p_config[aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST] 194 if ptype == aconsts.PUBLISH_TYPE_UNSOLICITED else 195 s_config[aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST]), 196 "Discovery mismatch: match filter") 197 198 # Subscriber: send message to peer (Publisher) 199 s_dut.droid.wifiAwareSendMessage(s_disc_id, peer_id_on_sub, 200 self.get_next_msg_id(), self.query_msg, 201 self.msg_retx_count) 202 autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_MESSAGE_SENT) 203 204 # Publisher: wait for received message 205 pub_rx_msg_event = autils.wait_for_event( 206 p_dut, aconsts.SESSION_CB_ON_MESSAGE_RECEIVED) 207 peer_id_on_pub = pub_rx_msg_event["data"][aconsts.SESSION_CB_KEY_PEER_ID] 208 209 # Publisher: validate contents of message 210 asserts.assert_equal( 211 pub_rx_msg_event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING], 212 self.query_msg, "Subscriber -> Publisher message corrupted") 213 214 # Publisher: send message to peer (Subscriber) 215 p_dut.droid.wifiAwareSendMessage(p_disc_id, peer_id_on_pub, 216 self.get_next_msg_id(), self.response_msg, 217 self.msg_retx_count) 218 autils.wait_for_event(p_dut, aconsts.SESSION_CB_ON_MESSAGE_SENT) 219 220 # Subscriber: wait for received message 221 sub_rx_msg_event = autils.wait_for_event( 222 s_dut, aconsts.SESSION_CB_ON_MESSAGE_RECEIVED) 223 224 # Subscriber: validate contents of message 225 asserts.assert_equal( 226 sub_rx_msg_event["data"][aconsts.SESSION_CB_KEY_PEER_ID], 227 peer_id_on_sub, 228 "Subscriber received message from different peer ID then discovery!?") 229 autils.assert_equal_strings( 230 sub_rx_msg_event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING], 231 self.response_msg, "Publisher -> Subscriber message corrupted") 232 233 # Subscriber: validate that we're not getting another Service Discovery 234 autils.fail_on_event(s_dut, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) 235 236 # Publisher: update publish and wait for confirmation 237 p_config[aconsts.DISCOVERY_KEY_SSI] = "something else" 238 p_dut.droid.wifiAwareUpdatePublish(p_disc_id, p_config) 239 autils.wait_for_event(p_dut, aconsts.SESSION_CB_ON_SESSION_CONFIG_UPDATED) 240 241 # Subscriber: expect a new service discovery 242 discovery_event = autils.wait_for_event( 243 s_dut, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) 244 245 # Subscriber: validate contents of discovery 246 autils.assert_equal_strings( 247 bytes(discovery_event["data"][ 248 aconsts.SESSION_CB_KEY_SERVICE_SPECIFIC_INFO]).decode("utf-8"), 249 p_config[aconsts.DISCOVERY_KEY_SSI], 250 "Discovery mismatch (after pub update): service specific info (SSI)") 251 asserts.assert_equal( 252 autils.decode_list( 253 discovery_event["data"][aconsts.SESSION_CB_KEY_MATCH_FILTER_LIST]), 254 autils.decode_list(p_config[aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST] 255 if ptype == aconsts.PUBLISH_TYPE_UNSOLICITED else 256 s_config[aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST]), 257 "Discovery mismatch: match filter") 258 259 # Subscribe: update subscribe and wait for confirmation 260 s_config = self.create_subscribe_config( 261 s_dut.aware_capabilities, 262 stype, 263 payload_size, 264 ttl=0, 265 term_ind_on=False, 266 null_match=False) 267 s_dut.droid.wifiAwareUpdateSubscribe(s_disc_id, s_config) 268 autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_SESSION_CONFIG_UPDATED) 269 270 # Publisher+Subscriber: Terminate sessions 271 p_dut.droid.wifiAwareDestroyDiscoverySession(p_disc_id) 272 s_dut.droid.wifiAwareDestroyDiscoverySession(s_disc_id) 273 274 # sleep for timeout period and then verify all 'fail_on_event' together 275 time.sleep(autils.EVENT_TIMEOUT) 276 277 # verify that there were no other events 278 autils.verify_no_more_events(p_dut, timeout=0) 279 autils.verify_no_more_events(s_dut, timeout=0) 280 281 # verify that forbidden callbacks aren't called 282 autils.validate_forbidden_callbacks(p_dut, {aconsts.CB_EV_MATCH: 0}) 283 284 def verify_discovery_session_term(self, dut, disc_id, config, is_publish, 285 term_ind_on): 286 """Utility to verify that the specified discovery session has terminated (by 287 waiting for the TTL and then attempting to reconfigure). 288 289 Args: 290 dut: device under test 291 disc_id: discovery id for the existing session 292 config: configuration of the existing session 293 is_publish: True if the configuration was publish, False if subscribe 294 term_ind_on: True if a termination indication is expected, False otherwise 295 """ 296 # Wait for session termination 297 if term_ind_on: 298 autils.wait_for_event( 299 dut, 300 autils.decorate_event(aconsts.SESSION_CB_ON_SESSION_TERMINATED, 301 disc_id)) 302 else: 303 # can't defer wait to end since in any case have to wait for session to 304 # expire 305 autils.fail_on_event( 306 dut, 307 autils.decorate_event(aconsts.SESSION_CB_ON_SESSION_TERMINATED, 308 disc_id)) 309 310 # Validate that session expired by trying to configure it (expect failure) 311 config[aconsts.DISCOVERY_KEY_SSI] = "something else" 312 if is_publish: 313 dut.droid.wifiAwareUpdatePublish(disc_id, config) 314 else: 315 dut.droid.wifiAwareUpdateSubscribe(disc_id, config) 316 317 # The response to update discovery session is: 318 # term_ind_on=True: session was cleaned-up so won't get an explicit failure, but won't get a 319 # success either. Can check for no SESSION_CB_ON_SESSION_CONFIG_UPDATED but 320 # will defer to the end of the test (no events on queue). 321 # term_ind_on=False: session was not cleaned-up (yet). So expect 322 # SESSION_CB_ON_SESSION_CONFIG_FAILED. 323 if not term_ind_on: 324 autils.wait_for_event( 325 dut, 326 autils.decorate_event(aconsts.SESSION_CB_ON_SESSION_CONFIG_FAILED, 327 disc_id)) 328 329 def positive_ttl_test_utility(self, is_publish, ptype, stype, term_ind_on): 330 """Utility which runs a positive discovery session TTL configuration test 331 332 Iteration 1: Verify session started with TTL 333 Iteration 2: Verify session started without TTL and reconfigured with TTL 334 Iteration 3: Verify session started with (long) TTL and reconfigured with 335 (short) TTL 336 337 Args: 338 is_publish: True if testing publish, False if testing subscribe 339 ptype: Publish discovery type (used if is_publish is True) 340 stype: Subscribe discovery type (used if is_publish is False) 341 term_ind_on: Configuration of termination indication 342 """ 343 SHORT_TTL = 5 # 5 seconds 344 LONG_TTL = 100 # 100 seconds 345 dut = self.android_devices[0] 346 347 # Attach and wait for confirmation 348 id = dut.droid.wifiAwareAttach(False) 349 autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED) 350 351 # Iteration 1: Start discovery session with TTL 352 config = self.create_base_config(dut.aware_capabilities, is_publish, ptype, 353 stype, self.PAYLOAD_SIZE_TYPICAL, 354 SHORT_TTL, term_ind_on, False) 355 if is_publish: 356 disc_id = dut.droid.wifiAwarePublish(id, config, True) 357 autils.wait_for_event(dut, 358 autils.decorate_event( 359 aconsts.SESSION_CB_ON_PUBLISH_STARTED, disc_id)) 360 else: 361 disc_id = dut.droid.wifiAwareSubscribe(id, config, True) 362 autils.wait_for_event( 363 dut, 364 autils.decorate_event(aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, 365 disc_id)) 366 367 # Wait for session termination & verify 368 self.verify_discovery_session_term(dut, disc_id, config, is_publish, 369 term_ind_on) 370 371 # Iteration 2: Start a discovery session without TTL 372 config = self.create_base_config(dut.aware_capabilities, is_publish, ptype, 373 stype, self.PAYLOAD_SIZE_TYPICAL, 0, 374 term_ind_on, False) 375 if is_publish: 376 disc_id = dut.droid.wifiAwarePublish(id, config, True) 377 autils.wait_for_event(dut, 378 autils.decorate_event( 379 aconsts.SESSION_CB_ON_PUBLISH_STARTED, disc_id)) 380 else: 381 disc_id = dut.droid.wifiAwareSubscribe(id, config, True) 382 autils.wait_for_event( 383 dut, 384 autils.decorate_event(aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, 385 disc_id)) 386 387 # Update with a TTL 388 config = self.create_base_config(dut.aware_capabilities, is_publish, ptype, 389 stype, self.PAYLOAD_SIZE_TYPICAL, 390 SHORT_TTL, term_ind_on, False) 391 if is_publish: 392 dut.droid.wifiAwareUpdatePublish(disc_id, config) 393 else: 394 dut.droid.wifiAwareUpdateSubscribe(disc_id, config) 395 autils.wait_for_event( 396 dut, 397 autils.decorate_event(aconsts.SESSION_CB_ON_SESSION_CONFIG_UPDATED, 398 disc_id)) 399 400 # Wait for session termination & verify 401 self.verify_discovery_session_term(dut, disc_id, config, is_publish, 402 term_ind_on) 403 404 # Iteration 3: Start a discovery session with (long) TTL 405 config = self.create_base_config(dut.aware_capabilities, is_publish, ptype, 406 stype, self.PAYLOAD_SIZE_TYPICAL, LONG_TTL, 407 term_ind_on, False) 408 if is_publish: 409 disc_id = dut.droid.wifiAwarePublish(id, config, True) 410 autils.wait_for_event(dut, 411 autils.decorate_event( 412 aconsts.SESSION_CB_ON_PUBLISH_STARTED, disc_id)) 413 else: 414 disc_id = dut.droid.wifiAwareSubscribe(id, config, True) 415 autils.wait_for_event( 416 dut, 417 autils.decorate_event(aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, 418 disc_id)) 419 420 # Update with a TTL 421 config = self.create_base_config(dut.aware_capabilities, is_publish, ptype, 422 stype, self.PAYLOAD_SIZE_TYPICAL, 423 SHORT_TTL, term_ind_on, False) 424 if is_publish: 425 dut.droid.wifiAwareUpdatePublish(disc_id, config) 426 else: 427 dut.droid.wifiAwareUpdateSubscribe(disc_id, config) 428 autils.wait_for_event( 429 dut, 430 autils.decorate_event(aconsts.SESSION_CB_ON_SESSION_CONFIG_UPDATED, 431 disc_id)) 432 433 # Wait for session termination & verify 434 self.verify_discovery_session_term(dut, disc_id, config, is_publish, 435 term_ind_on) 436 437 # verify that there were no other events 438 autils.verify_no_more_events(dut) 439 440 # verify that forbidden callbacks aren't called 441 if not term_ind_on: 442 autils.validate_forbidden_callbacks(dut, { 443 aconsts.CB_EV_PUBLISH_TERMINATED: 0, 444 aconsts.CB_EV_SUBSCRIBE_TERMINATED: 0 445 }) 446 447 def discovery_mismatch_test_utility(self, 448 is_expected_to_pass, 449 p_type, 450 s_type, 451 p_service_name=None, 452 s_service_name=None, 453 p_mf_1=None, 454 s_mf_1=None): 455 """Utility which runs the negative discovery test for mismatched service 456 configs. 457 458 Args: 459 is_expected_to_pass: True if positive test, False if negative 460 p_type: Publish discovery type 461 s_type: Subscribe discovery type 462 p_service_name: Publish service name (or None to leave unchanged) 463 s_service_name: Subscribe service name (or None to leave unchanged) 464 p_mf_1: Publish match filter element [1] (or None to leave unchanged) 465 s_mf_1: Subscribe match filter element [1] (or None to leave unchanged) 466 """ 467 p_dut = self.android_devices[0] 468 p_dut.pretty_name = "Publisher" 469 s_dut = self.android_devices[1] 470 s_dut.pretty_name = "Subscriber" 471 472 # create configurations 473 p_config = self.create_publish_config( 474 p_dut.aware_capabilities, 475 p_type, 476 self.PAYLOAD_SIZE_TYPICAL, 477 ttl=0, 478 term_ind_on=False, 479 null_match=False) 480 if p_service_name is not None: 481 p_config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = p_service_name 482 if p_mf_1 is not None: 483 p_config[aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST] = autils.encode_list( 484 [(10).to_bytes(1, byteorder="big"), 485 p_mf_1, 486 bytes(range(40))]) 487 s_config = self.create_publish_config( 488 s_dut.aware_capabilities, 489 s_type, 490 self.PAYLOAD_SIZE_TYPICAL, 491 ttl=0, 492 term_ind_on=False, 493 null_match=False) 494 if s_service_name is not None: 495 s_config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = s_service_name 496 if s_mf_1 is not None: 497 s_config[aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST] = autils.encode_list( 498 [(10).to_bytes(1, byteorder="big"), 499 s_mf_1, 500 bytes(range(40))]) 501 502 p_id = p_dut.droid.wifiAwareAttach(False) 503 autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED) 504 time.sleep(self.device_startup_offset) 505 s_id = s_dut.droid.wifiAwareAttach(False) 506 autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED) 507 508 # Publisher: start publish and wait for confirmation 509 p_disc_id = p_dut.droid.wifiAwarePublish(p_id, p_config) 510 autils.wait_for_event(p_dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED) 511 512 # Subscriber: start subscribe and wait for confirmation 513 s_disc_id = s_dut.droid.wifiAwareSubscribe(s_id, s_config) 514 autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED) 515 516 # Subscriber: fail on service discovery 517 if is_expected_to_pass: 518 autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) 519 else: 520 autils.fail_on_event(s_dut, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) 521 522 # Publisher+Subscriber: Terminate sessions 523 p_dut.droid.wifiAwareDestroyDiscoverySession(p_disc_id) 524 s_dut.droid.wifiAwareDestroyDiscoverySession(s_disc_id) 525 526 # verify that there were no other events (including terminations) 527 time.sleep(autils.EVENT_TIMEOUT) 528 autils.verify_no_more_events(p_dut, timeout=0) 529 autils.verify_no_more_events(s_dut, timeout=0) 530 531 532 ####################################### 533 # Positive tests key: 534 # 535 # names is: test_<pub_type>_<sub_type>_<size> 536 # where: 537 # 538 # pub_type: Type of publish discovery session: unsolicited or solicited. 539 # sub_type: Type of subscribe discovery session: passive or active. 540 # size: Size of payload fields (service name, service specific info, and match 541 # filter: typical, max, or min. 542 ####################################### 543 544 @test_tracker_info(uuid="954ebbde-ed2b-4f04-9e68-88239187d69d") 545 def test_positive_unsolicited_passive_typical(self): 546 """Functional test case / Discovery test cases / positive test case: 547 - Solicited publish + passive subscribe 548 - Typical payload fields size 549 550 Verifies that discovery and message exchange succeeds. 551 """ 552 self.positive_discovery_test_utility( 553 ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, 554 stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, 555 payload_size=self.PAYLOAD_SIZE_TYPICAL) 556 557 @test_tracker_info(uuid="67fb22bb-6985-4345-95a4-90b76681a58b") 558 def test_positive_unsolicited_passive_min(self): 559 """Functional test case / Discovery test cases / positive test case: 560 - Solicited publish + passive subscribe 561 - Minimal payload fields size 562 563 Verifies that discovery and message exchange succeeds. 564 """ 565 self.positive_discovery_test_utility( 566 ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, 567 stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, 568 payload_size=self.PAYLOAD_SIZE_MIN) 569 570 @test_tracker_info(uuid="a02a47b9-41bb-47bb-883b-921024a2c30d") 571 def test_positive_unsolicited_passive_max(self): 572 """Functional test case / Discovery test cases / positive test case: 573 - Solicited publish + passive subscribe 574 - Maximal payload fields size 575 576 Verifies that discovery and message exchange succeeds. 577 """ 578 self.positive_discovery_test_utility( 579 ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, 580 stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, 581 payload_size=self.PAYLOAD_SIZE_MAX) 582 583 @test_tracker_info(uuid="586c657f-2388-4e7a-baee-9bce2f3d1a16") 584 def test_positive_solicited_active_typical(self): 585 """Functional test case / Discovery test cases / positive test case: 586 - Unsolicited publish + active subscribe 587 - Typical payload fields size 588 589 Verifies that discovery and message exchange succeeds. 590 """ 591 self.positive_discovery_test_utility( 592 ptype=aconsts.PUBLISH_TYPE_SOLICITED, 593 stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, 594 payload_size=self.PAYLOAD_SIZE_TYPICAL) 595 596 @test_tracker_info(uuid="5369e4ff-f406-48c5-b41a-df38ec340146") 597 def test_positive_solicited_active_min(self): 598 """Functional test case / Discovery test cases / positive test case: 599 - Unsolicited publish + active subscribe 600 - Minimal payload fields size 601 602 Verifies that discovery and message exchange succeeds. 603 """ 604 self.positive_discovery_test_utility( 605 ptype=aconsts.PUBLISH_TYPE_SOLICITED, 606 stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, 607 payload_size=self.PAYLOAD_SIZE_MIN) 608 609 @test_tracker_info(uuid="634c6eb8-2c4f-42bd-9bbb-d874d0ec22f3") 610 def test_positive_solicited_active_max(self): 611 """Functional test case / Discovery test cases / positive test case: 612 - Unsolicited publish + active subscribe 613 - Maximal payload fields size 614 615 Verifies that discovery and message exchange succeeds. 616 """ 617 self.positive_discovery_test_utility( 618 ptype=aconsts.PUBLISH_TYPE_SOLICITED, 619 stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, 620 payload_size=self.PAYLOAD_SIZE_MAX) 621 622 ####################################### 623 # TTL tests key: 624 # 625 # names is: test_ttl_<pub_type|sub_type>_<term_ind> 626 # where: 627 # 628 # pub_type: Type of publish discovery session: unsolicited or solicited. 629 # sub_type: Type of subscribe discovery session: passive or active. 630 # term_ind: ind_on or ind_off 631 ####################################### 632 633 @test_tracker_info(uuid="9d7e758e-e0e2-4550-bcee-bfb6a2bff63e") 634 def test_ttl_unsolicited_ind_on(self): 635 """Functional test case / Discovery test cases / TTL test case: 636 - Unsolicited publish 637 - Termination indication enabled 638 """ 639 self.positive_ttl_test_utility( 640 is_publish=True, 641 ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, 642 stype=None, 643 term_ind_on=True) 644 645 @test_tracker_info(uuid="48fd69bc-cc2a-4f65-a0a1-63d7c1720702") 646 def test_ttl_unsolicited_ind_off(self): 647 """Functional test case / Discovery test cases / TTL test case: 648 - Unsolicited publish 649 - Termination indication disabled 650 """ 651 self.positive_ttl_test_utility( 652 is_publish=True, 653 ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, 654 stype=None, 655 term_ind_on=False) 656 657 @test_tracker_info(uuid="afb75fc1-9ba7-446a-b5ed-7cd37ab51b1c") 658 def test_ttl_solicited_ind_on(self): 659 """Functional test case / Discovery test cases / TTL test case: 660 - Solicited publish 661 - Termination indication enabled 662 """ 663 self.positive_ttl_test_utility( 664 is_publish=True, 665 ptype=aconsts.PUBLISH_TYPE_SOLICITED, 666 stype=None, 667 term_ind_on=True) 668 669 @test_tracker_info(uuid="703311a6-e444-4055-94ee-ea9b9b71799e") 670 def test_ttl_solicited_ind_off(self): 671 """Functional test case / Discovery test cases / TTL test case: 672 - Solicited publish 673 - Termination indication disabled 674 """ 675 self.positive_ttl_test_utility( 676 is_publish=True, 677 ptype=aconsts.PUBLISH_TYPE_SOLICITED, 678 stype=None, 679 term_ind_on=False) 680 681 @test_tracker_info(uuid="38a541c4-ff55-4387-87b7-4d940489da9d") 682 def test_ttl_passive_ind_on(self): 683 """Functional test case / Discovery test cases / TTL test case: 684 - Passive subscribe 685 - Termination indication enabled 686 """ 687 self.positive_ttl_test_utility( 688 is_publish=False, 689 ptype=None, 690 stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, 691 term_ind_on=True) 692 693 @test_tracker_info(uuid="ba971e12-b0ca-417c-a1b5-9451598de47d") 694 def test_ttl_passive_ind_off(self): 695 """Functional test case / Discovery test cases / TTL test case: 696 - Passive subscribe 697 - Termination indication disabled 698 """ 699 self.positive_ttl_test_utility( 700 is_publish=False, 701 ptype=None, 702 stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, 703 term_ind_on=False) 704 705 @test_tracker_info(uuid="7b5d96f2-2415-4b98-9a51-32957f0679a0") 706 def test_ttl_active_ind_on(self): 707 """Functional test case / Discovery test cases / TTL test case: 708 - Active subscribe 709 - Termination indication enabled 710 """ 711 self.positive_ttl_test_utility( 712 is_publish=False, 713 ptype=None, 714 stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, 715 term_ind_on=True) 716 717 @test_tracker_info(uuid="c9268eca-0a30-42dd-8e6c-b8b0b84697fb") 718 def test_ttl_active_ind_off(self): 719 """Functional test case / Discovery test cases / TTL test case: 720 - Active subscribe 721 - Termination indication disabled 722 """ 723 self.positive_ttl_test_utility( 724 is_publish=False, 725 ptype=None, 726 stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, 727 term_ind_on=False) 728 729 ####################################### 730 # Mismatched service name tests key: 731 # 732 # names is: test_mismatch_service_name_<pub_type>_<sub_type> 733 # where: 734 # 735 # pub_type: Type of publish discovery session: unsolicited or solicited. 736 # sub_type: Type of subscribe discovery session: passive or active. 737 ####################################### 738 739 @test_tracker_info(uuid="175415e9-7d07-40d0-95f0-3a5f91ea4711") 740 def test_mismatch_service_name_unsolicited_passive(self): 741 """Functional test case / Discovery test cases / Mismatch service name 742 - Unsolicited publish 743 - Passive subscribe 744 """ 745 self.discovery_mismatch_test_utility( 746 is_expected_to_pass=False, 747 p_type=aconsts.PUBLISH_TYPE_UNSOLICITED, 748 s_type=aconsts.SUBSCRIBE_TYPE_PASSIVE, 749 p_service_name="GoogleTestServiceXXX", 750 s_service_name="GoogleTestServiceYYY") 751 752 @test_tracker_info(uuid="c22a54ce-9e46-47a5-ac44-831faf93d317") 753 def test_mismatch_service_name_solicited_active(self): 754 """Functional test case / Discovery test cases / Mismatch service name 755 - Solicited publish 756 - Active subscribe 757 """ 758 self.discovery_mismatch_test_utility( 759 is_expected_to_pass=False, 760 p_type=aconsts.PUBLISH_TYPE_SOLICITED, 761 s_type=aconsts.SUBSCRIBE_TYPE_ACTIVE, 762 p_service_name="GoogleTestServiceXXX", 763 s_service_name="GoogleTestServiceYYY") 764 765 ####################################### 766 # Mismatched discovery session type tests key: 767 # 768 # names is: test_mismatch_service_type_<pub_type>_<sub_type> 769 # where: 770 # 771 # pub_type: Type of publish discovery session: unsolicited or solicited. 772 # sub_type: Type of subscribe discovery session: passive or active. 773 ####################################### 774 775 @test_tracker_info(uuid="4806f631-d9eb-45fd-9e75-24674962770f") 776 def test_mismatch_service_type_unsolicited_active(self): 777 """Functional test case / Discovery test cases / Mismatch service name 778 - Unsolicited publish 779 - Active subscribe 780 """ 781 self.discovery_mismatch_test_utility( 782 is_expected_to_pass=True, 783 p_type=aconsts.PUBLISH_TYPE_UNSOLICITED, 784 s_type=aconsts.SUBSCRIBE_TYPE_ACTIVE) 785 786 @test_tracker_info(uuid="12d648fd-b8fa-4c0f-9467-95e2366047de") 787 def test_mismatch_service_type_solicited_passive(self): 788 """Functional test case / Discovery test cases / Mismatch service name 789 - Unsolicited publish 790 - Active subscribe 791 """ 792 self.discovery_mismatch_test_utility( 793 is_expected_to_pass=False, 794 p_type=aconsts.PUBLISH_TYPE_SOLICITED, 795 s_type=aconsts.SUBSCRIBE_TYPE_PASSIVE) 796 797 ####################################### 798 # Mismatched discovery match filter tests key: 799 # 800 # names is: test_mismatch_match_filter_<pub_type>_<sub_type> 801 # where: 802 # 803 # pub_type: Type of publish discovery session: unsolicited or solicited. 804 # sub_type: Type of subscribe discovery session: passive or active. 805 ####################################### 806 807 @test_tracker_info(uuid="d98454cb-64af-4266-8fed-f0b545a2d7c4") 808 def test_mismatch_match_filter_unsolicited_passive(self): 809 """Functional test case / Discovery test cases / Mismatch match filter 810 - Unsolicited publish 811 - Passive subscribe 812 """ 813 self.discovery_mismatch_test_utility( 814 is_expected_to_pass=False, 815 p_type=aconsts.PUBLISH_TYPE_UNSOLICITED, 816 s_type=aconsts.SUBSCRIBE_TYPE_PASSIVE, 817 p_mf_1="hello there string", 818 s_mf_1="goodbye there string") 819 820 @test_tracker_info(uuid="663c1008-ae11-4e1a-87c7-c311d83f481c") 821 def test_mismatch_match_filter_solicited_active(self): 822 """Functional test case / Discovery test cases / Mismatch match filter 823 - Solicited publish 824 - Active subscribe 825 """ 826 self.discovery_mismatch_test_utility( 827 is_expected_to_pass=False, 828 p_type=aconsts.PUBLISH_TYPE_SOLICITED, 829 s_type=aconsts.SUBSCRIBE_TYPE_ACTIVE, 830 p_mf_1="hello there string", 831 s_mf_1="goodbye there string") 832 833 ####################################### 834 # Multiple concurrent services 835 ####################################### 836 837 def run_multiple_concurrent_services(self, type_x, type_y): 838 """Validate multiple identical discovery services running on both devices: 839 - DUT1 & DUT2 running Publish for X 840 - DUT1 & DUT2 running Publish for Y 841 - DUT1 Subscribes for X 842 - DUT2 Subscribes for Y 843 Message exchanges. 844 845 Note: test requires that devices support 2 publish sessions concurrently. 846 The test will be skipped if the devices are not capable. 847 848 Args: 849 type_x, type_y: A list of [ptype, stype] of the publish and subscribe 850 types for services X and Y respectively. 851 """ 852 dut1 = self.android_devices[0] 853 dut2 = self.android_devices[1] 854 855 X_SERVICE_NAME = "ServiceXXX" 856 Y_SERVICE_NAME = "ServiceYYY" 857 858 asserts.skip_if(dut1.aware_capabilities[aconsts.CAP_MAX_PUBLISHES] < 2 or 859 dut2.aware_capabilities[aconsts.CAP_MAX_PUBLISHES] < 2, 860 "Devices do not support 2 publish sessions") 861 862 # attach and wait for confirmation 863 id1 = dut1.droid.wifiAwareAttach(False) 864 autils.wait_for_event(dut1, aconsts.EVENT_CB_ON_ATTACHED) 865 time.sleep(self.device_startup_offset) 866 id2 = dut2.droid.wifiAwareAttach(False) 867 autils.wait_for_event(dut2, aconsts.EVENT_CB_ON_ATTACHED) 868 869 # DUT1 & DUT2: start publishing both X & Y services and wait for 870 # confirmations 871 dut1_x_pid = dut1.droid.wifiAwarePublish(id1, 872 autils.create_discovery_config( 873 X_SERVICE_NAME, type_x[0])) 874 event = autils.wait_for_event(dut1, aconsts.SESSION_CB_ON_PUBLISH_STARTED) 875 asserts.assert_equal(event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], 876 dut1_x_pid, 877 "Unexpected DUT1 X publish session discovery ID") 878 879 dut1_y_pid = dut1.droid.wifiAwarePublish(id1, 880 autils.create_discovery_config( 881 Y_SERVICE_NAME, type_y[0])) 882 event = autils.wait_for_event(dut1, aconsts.SESSION_CB_ON_PUBLISH_STARTED) 883 asserts.assert_equal(event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], 884 dut1_y_pid, 885 "Unexpected DUT1 Y publish session discovery ID") 886 887 dut2_x_pid = dut2.droid.wifiAwarePublish(id2, 888 autils.create_discovery_config( 889 X_SERVICE_NAME, type_x[0])) 890 event = autils.wait_for_event(dut2, aconsts.SESSION_CB_ON_PUBLISH_STARTED) 891 asserts.assert_equal(event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], 892 dut2_x_pid, 893 "Unexpected DUT2 X publish session discovery ID") 894 895 dut2_y_pid = dut2.droid.wifiAwarePublish(id2, 896 autils.create_discovery_config( 897 Y_SERVICE_NAME, type_y[0])) 898 event = autils.wait_for_event(dut2, aconsts.SESSION_CB_ON_PUBLISH_STARTED) 899 asserts.assert_equal(event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], 900 dut2_y_pid, 901 "Unexpected DUT2 Y publish session discovery ID") 902 903 # DUT1: start subscribing for X 904 dut1_x_sid = dut1.droid.wifiAwareSubscribe(id1, 905 autils.create_discovery_config( 906 X_SERVICE_NAME, type_x[1])) 907 autils.wait_for_event(dut1, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED) 908 909 # DUT2: start subscribing for Y 910 dut2_y_sid = dut2.droid.wifiAwareSubscribe(id2, 911 autils.create_discovery_config( 912 Y_SERVICE_NAME, type_y[1])) 913 autils.wait_for_event(dut2, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED) 914 915 # DUT1 & DUT2: wait for service discovery 916 event = autils.wait_for_event(dut1, 917 aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) 918 asserts.assert_equal(event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], 919 dut1_x_sid, 920 "Unexpected DUT1 X subscribe session discovery ID") 921 dut1_peer_id_for_dut2_x = event["data"][aconsts.SESSION_CB_KEY_PEER_ID] 922 923 event = autils.wait_for_event(dut2, 924 aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) 925 asserts.assert_equal(event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], 926 dut2_y_sid, 927 "Unexpected DUT2 Y subscribe session discovery ID") 928 dut2_peer_id_for_dut1_y = event["data"][aconsts.SESSION_CB_KEY_PEER_ID] 929 930 # DUT1.X send message to DUT2 931 x_msg = "Hello X on DUT2!" 932 dut1.droid.wifiAwareSendMessage(dut1_x_sid, dut1_peer_id_for_dut2_x, 933 self.get_next_msg_id(), x_msg, 934 self.msg_retx_count) 935 autils.wait_for_event(dut1, aconsts.SESSION_CB_ON_MESSAGE_SENT) 936 event = autils.wait_for_event(dut2, aconsts.SESSION_CB_ON_MESSAGE_RECEIVED) 937 asserts.assert_equal(event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], 938 dut2_x_pid, 939 "Unexpected publish session ID on DUT2 for meesage " 940 "received on service X") 941 asserts.assert_equal( 942 event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING], x_msg, 943 "Message on service X from DUT1 to DUT2 not received correctly") 944 945 # DUT2.Y send message to DUT1 946 y_msg = "Hello Y on DUT1!" 947 dut2.droid.wifiAwareSendMessage(dut2_y_sid, dut2_peer_id_for_dut1_y, 948 self.get_next_msg_id(), y_msg, 949 self.msg_retx_count) 950 autils.wait_for_event(dut2, aconsts.SESSION_CB_ON_MESSAGE_SENT) 951 event = autils.wait_for_event(dut1, aconsts.SESSION_CB_ON_MESSAGE_RECEIVED) 952 asserts.assert_equal(event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], 953 dut1_y_pid, 954 "Unexpected publish session ID on DUT1 for meesage " 955 "received on service Y") 956 asserts.assert_equal( 957 event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING], y_msg, 958 "Message on service Y from DUT2 to DUT1 not received correctly") 959 960 @test_tracker_info(uuid="eef80cf3-1fd2-4526-969b-6af2dce785d7") 961 def test_multiple_concurrent_services_both_unsolicited_passive(self): 962 """Validate multiple concurrent discovery sessions running on both devices. 963 - DUT1 & DUT2 running Publish for X 964 - DUT1 & DUT2 running Publish for Y 965 - DUT1 Subscribes for X 966 - DUT2 Subscribes for Y 967 Message exchanges. 968 969 Both sessions are Unsolicited/Passive. 970 971 Note: test requires that devices support 2 publish sessions concurrently. 972 The test will be skipped if the devices are not capable. 973 """ 974 self.run_multiple_concurrent_services( 975 type_x=[aconsts.PUBLISH_TYPE_UNSOLICITED, aconsts.SUBSCRIBE_TYPE_PASSIVE], 976 type_y=[aconsts.PUBLISH_TYPE_UNSOLICITED, aconsts.SUBSCRIBE_TYPE_PASSIVE]) 977 978 @test_tracker_info(uuid="46739f04-ab2b-4556-b1a4-9aa2774869b5") 979 def test_multiple_concurrent_services_both_solicited_active(self): 980 """Validate multiple concurrent discovery sessions running on both devices. 981 - DUT1 & DUT2 running Publish for X 982 - DUT1 & DUT2 running Publish for Y 983 - DUT1 Subscribes for X 984 - DUT2 Subscribes for Y 985 Message exchanges. 986 987 Both sessions are Solicited/Active. 988 989 Note: test requires that devices support 2 publish sessions concurrently. 990 The test will be skipped if the devices are not capable. 991 """ 992 self.run_multiple_concurrent_services( 993 type_x=[aconsts.PUBLISH_TYPE_SOLICITED, aconsts.SUBSCRIBE_TYPE_ACTIVE], 994 type_y=[aconsts.PUBLISH_TYPE_SOLICITED, aconsts.SUBSCRIBE_TYPE_ACTIVE]) 995 996 @test_tracker_info(uuid="5f8f7fd2-4a0e-4cca-8cbb-6d54353f2baa") 997 def test_multiple_concurrent_services_mix_unsolicited_solicited(self): 998 """Validate multiple concurrent discovery sessions running on both devices. 999 - DUT1 & DUT2 running Publish for X 1000 - DUT1 & DUT2 running Publish for Y 1001 - DUT1 Subscribes for X 1002 - DUT2 Subscribes for Y 1003 Message exchanges. 1004 1005 Session A is Unsolicited/Passive. 1006 Session B is Solicited/Active. 1007 1008 Note: test requires that devices support 2 publish sessions concurrently. 1009 The test will be skipped if the devices are not capable. 1010 """ 1011 self.run_multiple_concurrent_services( 1012 type_x=[aconsts.PUBLISH_TYPE_UNSOLICITED, aconsts.SUBSCRIBE_TYPE_PASSIVE], 1013 type_y=[aconsts.PUBLISH_TYPE_SOLICITED, aconsts.SUBSCRIBE_TYPE_ACTIVE]) 1014 1015 ######################################################### 1016 1017 @test_tracker_info(uuid="908ec896-fc7a-4ee4-b633-a2f042b74448") 1018 def test_upper_lower_service_name_equivalence(self): 1019 """Validate that Service Name is case-insensitive. Publish a service name 1020 with mixed case, subscribe to the same service name with alternative case 1021 and verify that discovery happens.""" 1022 p_dut = self.android_devices[0] 1023 s_dut = self.android_devices[1] 1024 1025 pub_service_name = "GoogleAbCdEf" 1026 sub_service_name = "GoogleaBcDeF" 1027 1028 autils.create_discovery_pair(p_dut, s_dut, 1029 p_config=autils.create_discovery_config( 1030 pub_service_name, 1031 aconsts.PUBLISH_TYPE_UNSOLICITED), 1032 s_config=autils.create_discovery_config( 1033 sub_service_name, 1034 aconsts.SUBSCRIBE_TYPE_PASSIVE), 1035 device_startup_offset=self.device_startup_offset) 1036