#!/usr/bin/python3.4 # # Copyright 2017 - The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import string import time from acts import asserts from acts.test_decorators import test_tracker_info from acts_contrib.test_utils.wifi.aware import aware_const as aconsts from acts_contrib.test_utils.wifi.aware import aware_test_utils as autils from acts_contrib.test_utils.wifi.aware.AwareBaseTest import AwareBaseTest from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest class DiscoveryTest(AwareBaseTest): """Set of tests for Wi-Fi Aware discovery.""" # configuration parameters used by tests PAYLOAD_SIZE_MIN = 0 PAYLOAD_SIZE_TYPICAL = 1 PAYLOAD_SIZE_MAX = 2 # message strings query_msg = "How are you doing? 你好嗎?" response_msg = "Doing ok - thanks! 做的不錯 - 謝謝!" # message re-transmit counter (increases reliability in open-environment) # Note: reliability of message transmission is tested elsewhere msg_retx_count = 5 # hard-coded max value, internal API def create_base_config(self, caps, is_publish, ptype, stype, payload_size, ttl, term_ind_on, null_match): """Create a base configuration based on input parameters. Args: caps: device capability dictionary is_publish: True if a publish config, else False ptype: unsolicited or solicited (used if is_publish is True) stype: passive or active (used if is_publish is False) payload_size: min, typical, max (PAYLOAD_SIZE_xx) ttl: time-to-live configuration (0 - forever) term_ind_on: is termination indication enabled null_match: null-out the middle match filter Returns: publish discovery configuration object. """ config = {} if is_publish: config[aconsts.DISCOVERY_KEY_DISCOVERY_TYPE] = ptype else: config[aconsts.DISCOVERY_KEY_DISCOVERY_TYPE] = stype config[aconsts.DISCOVERY_KEY_TTL] = ttl config[aconsts.DISCOVERY_KEY_TERM_CB_ENABLED] = term_ind_on if payload_size == self.PAYLOAD_SIZE_MIN: config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = "a" config[aconsts.DISCOVERY_KEY_SSI] = None config[aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST] = [] elif payload_size == self.PAYLOAD_SIZE_TYPICAL: config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = "GoogleTestServiceX" if is_publish: config[aconsts.DISCOVERY_KEY_SSI] = string.ascii_letters else: config[aconsts. DISCOVERY_KEY_SSI] = string.ascii_letters[:: -1] # reverse config[ aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST] = autils.encode_list( [(10).to_bytes(1, byteorder="big"), "hello there string" if not null_match else None, bytes(range(40))]) else: # PAYLOAD_SIZE_MAX config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = "VeryLong" + "X" * ( caps[aconsts.CAP_MAX_SERVICE_NAME_LEN] - 8) config[aconsts.DISCOVERY_KEY_SSI] = ( "P" if is_publish else "S") * caps[aconsts.CAP_MAX_SERVICE_SPECIFIC_INFO_LEN] mf = autils.construct_max_match_filter( caps[aconsts.CAP_MAX_MATCH_FILTER_LEN]) if null_match: mf[2] = None config[aconsts. DISCOVERY_KEY_MATCH_FILTER_LIST] = autils.encode_list(mf) return config def create_publish_config(self, caps, ptype, payload_size, ttl, term_ind_on, null_match): """Create a publish configuration based on input parameters. Args: caps: device capability dictionary ptype: unsolicited or solicited payload_size: min, typical, max (PAYLOAD_SIZE_xx) ttl: time-to-live configuration (0 - forever) term_ind_on: is termination indication enabled null_match: null-out the middle match filter Returns: publish discovery configuration object. """ return self.create_base_config(caps, True, ptype, None, payload_size, ttl, term_ind_on, null_match) def create_subscribe_config(self, caps, stype, payload_size, ttl, term_ind_on, null_match): """Create a subscribe configuration based on input parameters. Args: caps: device capability dictionary stype: passive or active payload_size: min, typical, max (PAYLOAD_SIZE_xx) ttl: time-to-live configuration (0 - forever) term_ind_on: is termination indication enabled null_match: null-out the middle match filter Returns: subscribe discovery configuration object. """ return self.create_base_config(caps, False, None, stype, payload_size, ttl, term_ind_on, null_match) def positive_discovery_test_utility(self, ptype, stype, payload_size): """Utility which runs a positive discovery test: - Discovery (publish/subscribe) with TTL=0 (non-self-terminating) - Exchange messages - Update publish/subscribe - Terminate Args: ptype: Publish discovery type stype: Subscribe discovery type payload_size: One of PAYLOAD_SIZE_* constants - MIN, TYPICAL, MAX """ p_dut = self.android_devices[0] p_dut.pretty_name = "Publisher" s_dut = self.android_devices[1] s_dut.pretty_name = "Subscriber" # Publisher+Subscriber: attach and wait for confirmation p_id = p_dut.droid.wifiAwareAttach(False) autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED) time.sleep(self.device_startup_offset) s_id = s_dut.droid.wifiAwareAttach(False) autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED) # Publisher: start publish and wait for confirmation p_config = self.create_publish_config( p_dut.aware_capabilities, ptype, payload_size, ttl=0, term_ind_on=False, null_match=False) p_disc_id = p_dut.droid.wifiAwarePublish(p_id, p_config) autils.wait_for_event(p_dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED) # Subscriber: start subscribe and wait for confirmation s_config = self.create_subscribe_config( s_dut.aware_capabilities, stype, payload_size, ttl=0, term_ind_on=False, null_match=True) s_disc_id = s_dut.droid.wifiAwareSubscribe(s_id, s_config) autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED) # Subscriber: wait for service discovery discovery_event = autils.wait_for_event( s_dut, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) peer_id_on_sub = discovery_event["data"][ aconsts.SESSION_CB_KEY_PEER_ID] # Subscriber: validate contents of discovery: # - SSI: publisher's # - Match filter: UNSOLICITED - publisher, SOLICITED - subscriber autils.assert_equal_strings( bytes(discovery_event["data"][ aconsts.SESSION_CB_KEY_SERVICE_SPECIFIC_INFO]).decode("utf-8"), p_config[aconsts.DISCOVERY_KEY_SSI], "Discovery mismatch: service specific info (SSI)") asserts.assert_equal( autils.decode_list(discovery_event["data"][ aconsts.SESSION_CB_KEY_MATCH_FILTER_LIST]), autils.decode_list( p_config[aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST] if ptype == aconsts.PUBLISH_TYPE_UNSOLICITED else s_config[ aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST]), "Discovery mismatch: match filter") # Subscriber: send message to peer (Publisher) s_dut.droid.wifiAwareSendMessage(s_disc_id, peer_id_on_sub, self.get_next_msg_id(), self.query_msg, self.msg_retx_count) autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_MESSAGE_SENT) # Publisher: wait for received message pub_rx_msg_event = autils.wait_for_event( p_dut, aconsts.SESSION_CB_ON_MESSAGE_RECEIVED) peer_id_on_pub = pub_rx_msg_event["data"][ aconsts.SESSION_CB_KEY_PEER_ID] # Publisher: validate contents of message asserts.assert_equal( pub_rx_msg_event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING], self.query_msg, "Subscriber -> Publisher message corrupted") # Publisher: send message to peer (Subscriber) p_dut.droid.wifiAwareSendMessage(p_disc_id, peer_id_on_pub, self.get_next_msg_id(), self.response_msg, self.msg_retx_count) autils.wait_for_event(p_dut, aconsts.SESSION_CB_ON_MESSAGE_SENT) # Subscriber: wait for received message sub_rx_msg_event = autils.wait_for_event( s_dut, aconsts.SESSION_CB_ON_MESSAGE_RECEIVED) # Subscriber: validate contents of message asserts.assert_equal( sub_rx_msg_event["data"][aconsts.SESSION_CB_KEY_PEER_ID], peer_id_on_sub, "Subscriber received message from different peer ID then discovery!?" ) autils.assert_equal_strings( sub_rx_msg_event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING], self.response_msg, "Publisher -> Subscriber message corrupted") # Subscriber: validate that we're not getting another Service Discovery autils.fail_on_event(s_dut, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) # Publisher: update publish and wait for confirmation p_config[aconsts.DISCOVERY_KEY_SSI] = "something else" p_dut.droid.wifiAwareUpdatePublish(p_disc_id, p_config) autils.wait_for_event(p_dut, aconsts.SESSION_CB_ON_SESSION_CONFIG_UPDATED) # Subscriber: expect a new service discovery discovery_event = autils.wait_for_event( s_dut, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) # Subscriber: validate contents of discovery autils.assert_equal_strings( bytes(discovery_event["data"][ aconsts.SESSION_CB_KEY_SERVICE_SPECIFIC_INFO]).decode("utf-8"), p_config[aconsts.DISCOVERY_KEY_SSI], "Discovery mismatch (after pub update): service specific info (SSI)" ) asserts.assert_equal( autils.decode_list(discovery_event["data"][ aconsts.SESSION_CB_KEY_MATCH_FILTER_LIST]), autils.decode_list( p_config[aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST] if ptype == aconsts.PUBLISH_TYPE_UNSOLICITED else s_config[ aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST]), "Discovery mismatch: match filter") asserts.assert_equal( peer_id_on_sub, discovery_event["data"][aconsts.SESSION_CB_KEY_PEER_ID], "Peer ID changed when publish was updated!?") # Subscribe: update subscribe and wait for confirmation s_config = self.create_subscribe_config( s_dut.aware_capabilities, stype, payload_size, ttl=0, term_ind_on=False, null_match=False) s_dut.droid.wifiAwareUpdateSubscribe(s_disc_id, s_config) autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_SESSION_CONFIG_UPDATED) # Publisher+Subscriber: Terminate sessions p_dut.droid.wifiAwareDestroyDiscoverySession(p_disc_id) s_dut.droid.wifiAwareDestroyDiscoverySession(s_disc_id) autils.wait_for_event(p_dut, aconsts.SESSION_CB_ON_SESSION_TERMINATED) autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_SESSION_TERMINATED) # verify that there were no other events autils.verify_no_more_events(p_dut, timeout=0) autils.verify_no_more_events(s_dut, timeout=0) # verify that forbidden callbacks aren't called autils.validate_forbidden_callbacks(p_dut, {aconsts.CB_EV_MATCH: 0}) def verify_discovery_session_term(self, dut, disc_id, config, is_publish, term_ind_on): """Utility to verify that the specified discovery session has terminated (by waiting for the TTL and then attempting to reconfigure). Args: dut: device under test disc_id: discovery id for the existing session config: configuration of the existing session is_publish: True if the configuration was publish, False if subscribe term_ind_on: True if a termination indication is expected, False otherwise """ # Wait for session termination if term_ind_on: autils.wait_for_event( dut, autils.decorate_event(aconsts.SESSION_CB_ON_SESSION_TERMINATED, disc_id)) else: # can't defer wait to end since in any case have to wait for session to # expire autils.fail_on_event( dut, autils.decorate_event(aconsts.SESSION_CB_ON_SESSION_TERMINATED, disc_id)) # Validate that session expired by trying to configure it (expect failure) config[aconsts.DISCOVERY_KEY_SSI] = "something else" if is_publish: dut.droid.wifiAwareUpdatePublish(disc_id, config) else: dut.droid.wifiAwareUpdateSubscribe(disc_id, config) # The response to update discovery session is: # term_ind_on=True: session was cleaned-up so won't get an explicit failure, but won't get a # success either. Can check for no SESSION_CB_ON_SESSION_CONFIG_UPDATED but # will defer to the end of the test (no events on queue). # term_ind_on=False: session was not cleaned-up (yet). So expect # SESSION_CB_ON_SESSION_CONFIG_FAILED. if not term_ind_on: autils.wait_for_event( dut, autils.decorate_event( aconsts.SESSION_CB_ON_SESSION_CONFIG_FAILED, disc_id)) def positive_ttl_test_utility(self, is_publish, ptype, stype, term_ind_on): """Utility which runs a positive discovery session TTL configuration test Iteration 1: Verify session started with TTL Iteration 2: Verify session started without TTL and reconfigured with TTL Iteration 3: Verify session started with (long) TTL and reconfigured with (short) TTL Args: is_publish: True if testing publish, False if testing subscribe ptype: Publish discovery type (used if is_publish is True) stype: Subscribe discovery type (used if is_publish is False) term_ind_on: Configuration of termination indication """ SHORT_TTL = 5 # 5 seconds LONG_TTL = 100 # 100 seconds dut = self.android_devices[0] # Attach and wait for confirmation id = dut.droid.wifiAwareAttach(False) autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED) # Iteration 1: Start discovery session with TTL config = self.create_base_config( dut.aware_capabilities, is_publish, ptype, stype, self.PAYLOAD_SIZE_TYPICAL, SHORT_TTL, term_ind_on, False) if is_publish: disc_id = dut.droid.wifiAwarePublish(id, config, True) autils.wait_for_event( dut, autils.decorate_event(aconsts.SESSION_CB_ON_PUBLISH_STARTED, disc_id)) else: disc_id = dut.droid.wifiAwareSubscribe(id, config, True) autils.wait_for_event( dut, autils.decorate_event(aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, disc_id)) # Wait for session termination & verify self.verify_discovery_session_term(dut, disc_id, config, is_publish, term_ind_on) # Iteration 2: Start a discovery session without TTL config = self.create_base_config( dut.aware_capabilities, is_publish, ptype, stype, self.PAYLOAD_SIZE_TYPICAL, 0, term_ind_on, False) if is_publish: disc_id = dut.droid.wifiAwarePublish(id, config, True) autils.wait_for_event( dut, autils.decorate_event(aconsts.SESSION_CB_ON_PUBLISH_STARTED, disc_id)) else: disc_id = dut.droid.wifiAwareSubscribe(id, config, True) autils.wait_for_event( dut, autils.decorate_event(aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, disc_id)) # Update with a TTL config = self.create_base_config( dut.aware_capabilities, is_publish, ptype, stype, self.PAYLOAD_SIZE_TYPICAL, SHORT_TTL, term_ind_on, False) if is_publish: dut.droid.wifiAwareUpdatePublish(disc_id, config) else: dut.droid.wifiAwareUpdateSubscribe(disc_id, config) autils.wait_for_event( dut, autils.decorate_event(aconsts.SESSION_CB_ON_SESSION_CONFIG_UPDATED, disc_id)) # Wait for session termination & verify self.verify_discovery_session_term(dut, disc_id, config, is_publish, term_ind_on) # Iteration 3: Start a discovery session with (long) TTL config = self.create_base_config( dut.aware_capabilities, is_publish, ptype, stype, self.PAYLOAD_SIZE_TYPICAL, LONG_TTL, term_ind_on, False) if is_publish: disc_id = dut.droid.wifiAwarePublish(id, config, True) autils.wait_for_event( dut, autils.decorate_event(aconsts.SESSION_CB_ON_PUBLISH_STARTED, disc_id)) else: disc_id = dut.droid.wifiAwareSubscribe(id, config, True) autils.wait_for_event( dut, autils.decorate_event(aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, disc_id)) # Update with a TTL config = self.create_base_config( dut.aware_capabilities, is_publish, ptype, stype, self.PAYLOAD_SIZE_TYPICAL, SHORT_TTL, term_ind_on, False) if is_publish: dut.droid.wifiAwareUpdatePublish(disc_id, config) else: dut.droid.wifiAwareUpdateSubscribe(disc_id, config) autils.wait_for_event( dut, autils.decorate_event(aconsts.SESSION_CB_ON_SESSION_CONFIG_UPDATED, disc_id)) # Wait for session termination & verify self.verify_discovery_session_term(dut, disc_id, config, is_publish, term_ind_on) # verify that there were no other events autils.verify_no_more_events(dut) # verify that forbidden callbacks aren't called if not term_ind_on: autils.validate_forbidden_callbacks( dut, { aconsts.CB_EV_PUBLISH_TERMINATED: 0, aconsts.CB_EV_SUBSCRIBE_TERMINATED: 0 }) def discovery_mismatch_test_utility(self, is_expected_to_pass, p_type, s_type, p_service_name=None, s_service_name=None, p_mf_1=None, s_mf_1=None): """Utility which runs the negative discovery test for mismatched service configs. Args: is_expected_to_pass: True if positive test, False if negative p_type: Publish discovery type s_type: Subscribe discovery type p_service_name: Publish service name (or None to leave unchanged) s_service_name: Subscribe service name (or None to leave unchanged) p_mf_1: Publish match filter element [1] (or None to leave unchanged) s_mf_1: Subscribe match filter element [1] (or None to leave unchanged) """ p_dut = self.android_devices[0] p_dut.pretty_name = "Publisher" s_dut = self.android_devices[1] s_dut.pretty_name = "Subscriber" # create configurations p_config = self.create_publish_config( p_dut.aware_capabilities, p_type, self.PAYLOAD_SIZE_TYPICAL, ttl=0, term_ind_on=False, null_match=False) if p_service_name is not None: p_config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = p_service_name if p_mf_1 is not None: p_config[ aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST] = autils.encode_list( [(10).to_bytes(1, byteorder="big"), p_mf_1, bytes(range(40))]) s_config = self.create_publish_config( s_dut.aware_capabilities, s_type, self.PAYLOAD_SIZE_TYPICAL, ttl=0, term_ind_on=False, null_match=False) if s_service_name is not None: s_config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = s_service_name if s_mf_1 is not None: s_config[ aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST] = autils.encode_list( [(10).to_bytes(1, byteorder="big"), s_mf_1, bytes(range(40))]) p_id = p_dut.droid.wifiAwareAttach(False) autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED) time.sleep(self.device_startup_offset) s_id = s_dut.droid.wifiAwareAttach(False) autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED) # Publisher: start publish and wait for confirmation p_disc_id = p_dut.droid.wifiAwarePublish(p_id, p_config) autils.wait_for_event(p_dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED) # Subscriber: start subscribe and wait for confirmation s_disc_id = s_dut.droid.wifiAwareSubscribe(s_id, s_config) autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED) # Subscriber: fail on service discovery if is_expected_to_pass: autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) else: autils.fail_on_event(s_dut, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) # Publisher+Subscriber: Terminate sessions p_dut.droid.wifiAwareDestroyDiscoverySession(p_disc_id) s_dut.droid.wifiAwareDestroyDiscoverySession(s_disc_id) autils.wait_for_event(p_dut, aconsts.SESSION_CB_ON_SESSION_TERMINATED) autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_SESSION_TERMINATED) # verify that there were no other events (including terminations) autils.verify_no_more_events(p_dut, timeout=0) autils.verify_no_more_events(s_dut, timeout=0) ####################################### # Positive tests key: # # names is: test___ # where: # # pub_type: Type of publish discovery session: unsolicited or solicited. # sub_type: Type of subscribe discovery session: passive or active. # size: Size of payload fields (service name, service specific info, and match # filter: typical, max, or min. ####################################### @test_tracker_info(uuid="954ebbde-ed2b-4f04-9e68-88239187d69d") @WifiBaseTest.wifi_test_wrap def test_positive_unsolicited_passive_typical(self): """Functional test case / Discovery test cases / positive test case: - Solicited publish + passive subscribe - Typical payload fields size Verifies that discovery and message exchange succeeds. """ self.positive_discovery_test_utility( ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, payload_size=self.PAYLOAD_SIZE_TYPICAL) @test_tracker_info(uuid="67fb22bb-6985-4345-95a4-90b76681a58b") def test_positive_unsolicited_passive_min(self): """Functional test case / Discovery test cases / positive test case: - Solicited publish + passive subscribe - Minimal payload fields size Verifies that discovery and message exchange succeeds. """ self.positive_discovery_test_utility( ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, payload_size=self.PAYLOAD_SIZE_MIN) @test_tracker_info(uuid="a02a47b9-41bb-47bb-883b-921024a2c30d") def test_positive_unsolicited_passive_max(self): """Functional test case / Discovery test cases / positive test case: - Solicited publish + passive subscribe - Maximal payload fields size Verifies that discovery and message exchange succeeds. """ self.positive_discovery_test_utility( ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, payload_size=self.PAYLOAD_SIZE_MAX) @test_tracker_info(uuid="586c657f-2388-4e7a-baee-9bce2f3d1a16") def test_positive_solicited_active_typical(self): """Functional test case / Discovery test cases / positive test case: - Unsolicited publish + active subscribe - Typical payload fields size Verifies that discovery and message exchange succeeds. """ self.positive_discovery_test_utility( ptype=aconsts.PUBLISH_TYPE_SOLICITED, stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, payload_size=self.PAYLOAD_SIZE_TYPICAL) @test_tracker_info(uuid="5369e4ff-f406-48c5-b41a-df38ec340146") def test_positive_solicited_active_min(self): """Functional test case / Discovery test cases / positive test case: - Unsolicited publish + active subscribe - Minimal payload fields size Verifies that discovery and message exchange succeeds. """ self.positive_discovery_test_utility( ptype=aconsts.PUBLISH_TYPE_SOLICITED, stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, payload_size=self.PAYLOAD_SIZE_MIN) @test_tracker_info(uuid="634c6eb8-2c4f-42bd-9bbb-d874d0ec22f3") def test_positive_solicited_active_max(self): """Functional test case / Discovery test cases / positive test case: - Unsolicited publish + active subscribe - Maximal payload fields size Verifies that discovery and message exchange succeeds. """ self.positive_discovery_test_utility( ptype=aconsts.PUBLISH_TYPE_SOLICITED, stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, payload_size=self.PAYLOAD_SIZE_MAX) ####################################### # TTL tests key: # # names is: test_ttl__ # where: # # pub_type: Type of publish discovery session: unsolicited or solicited. # sub_type: Type of subscribe discovery session: passive or active. # term_ind: ind_on or ind_off ####################################### @test_tracker_info(uuid="9d7e758e-e0e2-4550-bcee-bfb6a2bff63e") def test_ttl_unsolicited_ind_on(self): """Functional test case / Discovery test cases / TTL test case: - Unsolicited publish - Termination indication enabled """ self.positive_ttl_test_utility( is_publish=True, ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, stype=None, term_ind_on=True) @test_tracker_info(uuid="48fd69bc-cc2a-4f65-a0a1-63d7c1720702") def test_ttl_unsolicited_ind_off(self): """Functional test case / Discovery test cases / TTL test case: - Unsolicited publish - Termination indication disabled """ self.positive_ttl_test_utility( is_publish=True, ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, stype=None, term_ind_on=False) @test_tracker_info(uuid="afb75fc1-9ba7-446a-b5ed-7cd37ab51b1c") def test_ttl_solicited_ind_on(self): """Functional test case / Discovery test cases / TTL test case: - Solicited publish - Termination indication enabled """ self.positive_ttl_test_utility( is_publish=True, ptype=aconsts.PUBLISH_TYPE_SOLICITED, stype=None, term_ind_on=True) @test_tracker_info(uuid="703311a6-e444-4055-94ee-ea9b9b71799e") def test_ttl_solicited_ind_off(self): """Functional test case / Discovery test cases / TTL test case: - Solicited publish - Termination indication disabled """ self.positive_ttl_test_utility( is_publish=True, ptype=aconsts.PUBLISH_TYPE_SOLICITED, stype=None, term_ind_on=False) @test_tracker_info(uuid="38a541c4-ff55-4387-87b7-4d940489da9d") def test_ttl_passive_ind_on(self): """Functional test case / Discovery test cases / TTL test case: - Passive subscribe - Termination indication enabled """ self.positive_ttl_test_utility( is_publish=False, ptype=None, stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, term_ind_on=True) @test_tracker_info(uuid="ba971e12-b0ca-417c-a1b5-9451598de47d") def test_ttl_passive_ind_off(self): """Functional test case / Discovery test cases / TTL test case: - Passive subscribe - Termination indication disabled """ self.positive_ttl_test_utility( is_publish=False, ptype=None, stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, term_ind_on=False) @test_tracker_info(uuid="7b5d96f2-2415-4b98-9a51-32957f0679a0") def test_ttl_active_ind_on(self): """Functional test case / Discovery test cases / TTL test case: - Active subscribe - Termination indication enabled """ self.positive_ttl_test_utility( is_publish=False, ptype=None, stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, term_ind_on=True) @test_tracker_info(uuid="c9268eca-0a30-42dd-8e6c-b8b0b84697fb") def test_ttl_active_ind_off(self): """Functional test case / Discovery test cases / TTL test case: - Active subscribe - Termination indication disabled """ self.positive_ttl_test_utility( is_publish=False, ptype=None, stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, term_ind_on=False) ####################################### # Mismatched service name tests key: # # names is: test_mismatch_service_name__ # where: # # pub_type: Type of publish discovery session: unsolicited or solicited. # sub_type: Type of subscribe discovery session: passive or active. ####################################### @test_tracker_info(uuid="175415e9-7d07-40d0-95f0-3a5f91ea4711") def test_mismatch_service_name_unsolicited_passive(self): """Functional test case / Discovery test cases / Mismatch service name - Unsolicited publish - Passive subscribe """ self.discovery_mismatch_test_utility( is_expected_to_pass=False, p_type=aconsts.PUBLISH_TYPE_UNSOLICITED, s_type=aconsts.SUBSCRIBE_TYPE_PASSIVE, p_service_name="GoogleTestServiceXXX", s_service_name="GoogleTestServiceYYY") @test_tracker_info(uuid="c22a54ce-9e46-47a5-ac44-831faf93d317") def test_mismatch_service_name_solicited_active(self): """Functional test case / Discovery test cases / Mismatch service name - Solicited publish - Active subscribe """ self.discovery_mismatch_test_utility( is_expected_to_pass=False, p_type=aconsts.PUBLISH_TYPE_SOLICITED, s_type=aconsts.SUBSCRIBE_TYPE_ACTIVE, p_service_name="GoogleTestServiceXXX", s_service_name="GoogleTestServiceYYY") ####################################### # Mismatched discovery session type tests key: # # names is: test_mismatch_service_type__ # where: # # pub_type: Type of publish discovery session: unsolicited or solicited. # sub_type: Type of subscribe discovery session: passive or active. ####################################### @test_tracker_info(uuid="4806f631-d9eb-45fd-9e75-24674962770f") def test_mismatch_service_type_unsolicited_active(self): """Functional test case / Discovery test cases / Mismatch service name - Unsolicited publish - Active subscribe """ self.discovery_mismatch_test_utility( is_expected_to_pass=True, p_type=aconsts.PUBLISH_TYPE_UNSOLICITED, s_type=aconsts.SUBSCRIBE_TYPE_ACTIVE) @test_tracker_info(uuid="12d648fd-b8fa-4c0f-9467-95e2366047de") def test_mismatch_service_type_solicited_passive(self): """Functional test case / Discovery test cases / Mismatch service name - Unsolicited publish - Active subscribe """ self.discovery_mismatch_test_utility( is_expected_to_pass=False, p_type=aconsts.PUBLISH_TYPE_SOLICITED, s_type=aconsts.SUBSCRIBE_TYPE_PASSIVE) ####################################### # Mismatched discovery match filter tests key: # # names is: test_mismatch_match_filter__ # where: # # pub_type: Type of publish discovery session: unsolicited or solicited. # sub_type: Type of subscribe discovery session: passive or active. ####################################### @test_tracker_info(uuid="d98454cb-64af-4266-8fed-f0b545a2d7c4") def test_mismatch_match_filter_unsolicited_passive(self): """Functional test case / Discovery test cases / Mismatch match filter - Unsolicited publish - Passive subscribe """ self.discovery_mismatch_test_utility( is_expected_to_pass=False, p_type=aconsts.PUBLISH_TYPE_UNSOLICITED, s_type=aconsts.SUBSCRIBE_TYPE_PASSIVE, p_mf_1="hello there string", s_mf_1="goodbye there string") @test_tracker_info(uuid="663c1008-ae11-4e1a-87c7-c311d83f481c") def test_mismatch_match_filter_solicited_active(self): """Functional test case / Discovery test cases / Mismatch match filter - Solicited publish - Active subscribe """ self.discovery_mismatch_test_utility( is_expected_to_pass=False, p_type=aconsts.PUBLISH_TYPE_SOLICITED, s_type=aconsts.SUBSCRIBE_TYPE_ACTIVE, p_mf_1="hello there string", s_mf_1="goodbye there string") ####################################### # Multiple concurrent services ####################################### def run_multiple_concurrent_services(self, type_x, type_y): """Validate multiple identical discovery services running on both devices: - DUT1 & DUT2 running Publish for X - DUT1 & DUT2 running Publish for Y - DUT1 Subscribes for X - DUT2 Subscribes for Y Message exchanges. Note: test requires that devices support 2 publish sessions concurrently. The test will be skipped if the devices are not capable. Args: type_x, type_y: A list of [ptype, stype] of the publish and subscribe types for services X and Y respectively. """ dut1 = self.android_devices[0] dut2 = self.android_devices[1] X_SERVICE_NAME = "ServiceXXX" Y_SERVICE_NAME = "ServiceYYY" asserts.skip_if( dut1.aware_capabilities[aconsts.CAP_MAX_PUBLISHES] < 2 or dut2.aware_capabilities[aconsts.CAP_MAX_PUBLISHES] < 2, "Devices do not support 2 publish sessions") # attach and wait for confirmation id1 = dut1.droid.wifiAwareAttach(False) autils.wait_for_event(dut1, aconsts.EVENT_CB_ON_ATTACHED) time.sleep(self.device_startup_offset) id2 = dut2.droid.wifiAwareAttach(False) autils.wait_for_event(dut2, aconsts.EVENT_CB_ON_ATTACHED) # DUT1 & DUT2: start publishing both X & Y services and wait for # confirmations dut1_x_pid = dut1.droid.wifiAwarePublish( id1, autils.create_discovery_config(X_SERVICE_NAME, type_x[0])) event = autils.wait_for_event(dut1, aconsts.SESSION_CB_ON_PUBLISH_STARTED) asserts.assert_equal(event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], dut1_x_pid, "Unexpected DUT1 X publish session discovery ID") dut1_y_pid = dut1.droid.wifiAwarePublish( id1, autils.create_discovery_config(Y_SERVICE_NAME, type_y[0])) event = autils.wait_for_event(dut1, aconsts.SESSION_CB_ON_PUBLISH_STARTED) asserts.assert_equal(event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], dut1_y_pid, "Unexpected DUT1 Y publish session discovery ID") dut2_x_pid = dut2.droid.wifiAwarePublish( id2, autils.create_discovery_config(X_SERVICE_NAME, type_x[0])) event = autils.wait_for_event(dut2, aconsts.SESSION_CB_ON_PUBLISH_STARTED) asserts.assert_equal(event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], dut2_x_pid, "Unexpected DUT2 X publish session discovery ID") dut2_y_pid = dut2.droid.wifiAwarePublish( id2, autils.create_discovery_config(Y_SERVICE_NAME, type_y[0])) event = autils.wait_for_event(dut2, aconsts.SESSION_CB_ON_PUBLISH_STARTED) asserts.assert_equal(event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], dut2_y_pid, "Unexpected DUT2 Y publish session discovery ID") # DUT1: start subscribing for X dut1_x_sid = dut1.droid.wifiAwareSubscribe( id1, autils.create_discovery_config(X_SERVICE_NAME, type_x[1])) autils.wait_for_event(dut1, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED) # DUT2: start subscribing for Y dut2_y_sid = dut2.droid.wifiAwareSubscribe( id2, autils.create_discovery_config(Y_SERVICE_NAME, type_y[1])) autils.wait_for_event(dut2, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED) # DUT1 & DUT2: wait for service discovery event = autils.wait_for_event(dut1, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) asserts.assert_equal( event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], dut1_x_sid, "Unexpected DUT1 X subscribe session discovery ID") dut1_peer_id_for_dut2_x = event["data"][aconsts.SESSION_CB_KEY_PEER_ID] event = autils.wait_for_event(dut2, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) asserts.assert_equal( event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], dut2_y_sid, "Unexpected DUT2 Y subscribe session discovery ID") dut2_peer_id_for_dut1_y = event["data"][aconsts.SESSION_CB_KEY_PEER_ID] # DUT1.X send message to DUT2 x_msg = "Hello X on DUT2!" dut1.droid.wifiAwareSendMessage(dut1_x_sid, dut1_peer_id_for_dut2_x, self.get_next_msg_id(), x_msg, self.msg_retx_count) autils.wait_for_event(dut1, aconsts.SESSION_CB_ON_MESSAGE_SENT) event = autils.wait_for_event(dut2, aconsts.SESSION_CB_ON_MESSAGE_RECEIVED) asserts.assert_equal( event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], dut2_x_pid, "Unexpected publish session ID on DUT2 for meesage " "received on service X") asserts.assert_equal( event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING], x_msg, "Message on service X from DUT1 to DUT2 not received correctly") # DUT2.Y send message to DUT1 y_msg = "Hello Y on DUT1!" dut2.droid.wifiAwareSendMessage(dut2_y_sid, dut2_peer_id_for_dut1_y, self.get_next_msg_id(), y_msg, self.msg_retx_count) autils.wait_for_event(dut2, aconsts.SESSION_CB_ON_MESSAGE_SENT) event = autils.wait_for_event(dut1, aconsts.SESSION_CB_ON_MESSAGE_RECEIVED) asserts.assert_equal( event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], dut1_y_pid, "Unexpected publish session ID on DUT1 for meesage " "received on service Y") asserts.assert_equal( event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING], y_msg, "Message on service Y from DUT2 to DUT1 not received correctly") @test_tracker_info(uuid="eef80cf3-1fd2-4526-969b-6af2dce785d7") def test_multiple_concurrent_services_both_unsolicited_passive(self): """Validate multiple concurrent discovery sessions running on both devices. - DUT1 & DUT2 running Publish for X - DUT1 & DUT2 running Publish for Y - DUT1 Subscribes for X - DUT2 Subscribes for Y Message exchanges. Both sessions are Unsolicited/Passive. Note: test requires that devices support 2 publish sessions concurrently. The test will be skipped if the devices are not capable. """ self.run_multiple_concurrent_services( type_x=[ aconsts.PUBLISH_TYPE_UNSOLICITED, aconsts.SUBSCRIBE_TYPE_PASSIVE ], type_y=[ aconsts.PUBLISH_TYPE_UNSOLICITED, aconsts.SUBSCRIBE_TYPE_PASSIVE ]) @test_tracker_info(uuid="46739f04-ab2b-4556-b1a4-9aa2774869b5") def test_multiple_concurrent_services_both_solicited_active(self): """Validate multiple concurrent discovery sessions running on both devices. - DUT1 & DUT2 running Publish for X - DUT1 & DUT2 running Publish for Y - DUT1 Subscribes for X - DUT2 Subscribes for Y Message exchanges. Both sessions are Solicited/Active. Note: test requires that devices support 2 publish sessions concurrently. The test will be skipped if the devices are not capable. """ self.run_multiple_concurrent_services( type_x=[ aconsts.PUBLISH_TYPE_SOLICITED, aconsts.SUBSCRIBE_TYPE_ACTIVE ], type_y=[ aconsts.PUBLISH_TYPE_SOLICITED, aconsts.SUBSCRIBE_TYPE_ACTIVE ]) @test_tracker_info(uuid="5f8f7fd2-4a0e-4cca-8cbb-6d54353f2baa") def test_multiple_concurrent_services_mix_unsolicited_solicited(self): """Validate multiple concurrent discovery sessions running on both devices. - DUT1 & DUT2 running Publish for X - DUT1 & DUT2 running Publish for Y - DUT1 Subscribes for X - DUT2 Subscribes for Y Message exchanges. Session A is Unsolicited/Passive. Session B is Solicited/Active. Note: test requires that devices support 2 publish sessions concurrently. The test will be skipped if the devices are not capable. """ self.run_multiple_concurrent_services( type_x=[ aconsts.PUBLISH_TYPE_UNSOLICITED, aconsts.SUBSCRIBE_TYPE_PASSIVE ], type_y=[ aconsts.PUBLISH_TYPE_SOLICITED, aconsts.SUBSCRIBE_TYPE_ACTIVE ]) ######################################################### @test_tracker_info(uuid="908ec896-fc7a-4ee4-b633-a2f042b74448") def test_upper_lower_service_name_equivalence(self): """Validate that Service Name is case-insensitive. Publish a service name with mixed case, subscribe to the same service name with alternative case and verify that discovery happens.""" p_dut = self.android_devices[0] s_dut = self.android_devices[1] pub_service_name = "GoogleAbCdEf" sub_service_name = "GoogleaBcDeF" autils.create_discovery_pair( p_dut, s_dut, p_config=autils.create_discovery_config( pub_service_name, aconsts.PUBLISH_TYPE_UNSOLICITED), s_config=autils.create_discovery_config( sub_service_name, aconsts.SUBSCRIBE_TYPE_PASSIVE), device_startup_offset=self.device_startup_offset) ########################################################## def exchange_messages(self, p_dut, p_disc_id, s_dut, s_disc_id, peer_id_on_sub, session_name): """ Exchange message between Publisher and Subscriber on target discovery session Args: p_dut: Publisher device p_disc_id: Publish discovery session id s_dut: Subscriber device s_disc_id: Subscribe discovery session id peer_id_on_sub: Peer ID of the Publisher as seen on the Subscriber session_name: dictionary of discovery session name base on role("pub" or "sub") {role: {disc_id: name}} """ msg_template = "Hello {} from {} !" # Message send from Subscriber to Publisher s_to_p_msg = msg_template.format(session_name["pub"][p_disc_id], session_name["sub"][s_disc_id]) s_dut.droid.wifiAwareSendMessage(s_disc_id, peer_id_on_sub, self.get_next_msg_id(), s_to_p_msg, self.msg_retx_count) autils.wait_for_event(s_dut, autils.decorate_event(aconsts.SESSION_CB_ON_MESSAGE_SENT, s_disc_id)) event = autils.wait_for_event(p_dut, autils.decorate_event(aconsts.SESSION_CB_ON_MESSAGE_RECEIVED, p_disc_id)) asserts.assert_equal( event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING], s_to_p_msg, "Message on service %s from Subscriber to Publisher " "not received correctly" % session_name["pub"][p_disc_id]) peer_id_on_pub = event["data"][aconsts.SESSION_CB_KEY_PEER_ID] # Message send from Publisher to Subscriber p_to_s_msg = msg_template.format(session_name["sub"][s_disc_id], session_name["pub"][p_disc_id]) p_dut.droid.wifiAwareSendMessage(p_disc_id, peer_id_on_pub, self.get_next_msg_id(), p_to_s_msg, self.msg_retx_count) autils.wait_for_event( p_dut, autils.decorate_event(aconsts.SESSION_CB_ON_MESSAGE_SENT, p_disc_id)) event = autils.wait_for_event(s_dut, autils.decorate_event(aconsts.SESSION_CB_ON_MESSAGE_RECEIVED, s_disc_id)) asserts.assert_equal( event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING], p_to_s_msg, "Message on service %s from Publisher to Subscriber" "not received correctly" % session_name["sub"][s_disc_id]) def run_multiple_concurrent_services_same_name_diff_ssi(self, type_x, type_y): """Validate same service name with multiple service specific info on publisher and subscriber can see all service - p_dut running Publish X and Y - s_dut running subscribe A and B - subscribe A find X and Y - subscribe B find X and Y Message exchanges: - A to X and X to A - B to X and X to B - A to Y and Y to A - B to Y and Y to B Note: test requires that publisher device support 2 publish sessions concurrently, and subscriber device support 2 subscribe sessions concurrently. The test will be skipped if the devices are not capable. Args: type_x, type_y: A list of [ptype, stype] of the publish and subscribe types for services X and Y respectively. """ p_dut = self.android_devices[0] s_dut = self.android_devices[1] asserts.skip_if( p_dut.aware_capabilities[aconsts.CAP_MAX_PUBLISHES] < 2 or s_dut.aware_capabilities[aconsts.CAP_MAX_SUBSCRIBES] < 2, "Devices do not support 2 publish sessions or 2 subscribe sessions") SERVICE_NAME = "ServiceName" X_SERVICE_SSI = "ServiceSpecificInfoXXX" Y_SERVICE_SSI = "ServiceSpecificInfoYYY" use_id = True # attach and wait for confirmation p_id = p_dut.droid.wifiAwareAttach(False, None, use_id) autils.wait_for_event(p_dut, autils.decorate_event(aconsts.EVENT_CB_ON_ATTACHED, p_id)) time.sleep(self.device_startup_offset) s_id = s_dut.droid.wifiAwareAttach(False, None, use_id) autils.wait_for_event(s_dut, autils.decorate_event(aconsts.EVENT_CB_ON_ATTACHED, s_id)) # Publisher: start publishing both X & Y services and wait for confirmations p_disc_id_x = p_dut.droid.wifiAwarePublish( p_id, autils.create_discovery_config(SERVICE_NAME, type_x[0], X_SERVICE_SSI), use_id) event = autils.wait_for_event(p_dut, autils.decorate_event( aconsts.SESSION_CB_ON_PUBLISH_STARTED, p_disc_id_x)) p_disc_id_y = p_dut.droid.wifiAwarePublish( p_id, autils.create_discovery_config(SERVICE_NAME, type_x[0], Y_SERVICE_SSI), use_id) event = autils.wait_for_event(p_dut, autils.decorate_event( aconsts.SESSION_CB_ON_PUBLISH_STARTED, p_disc_id_y)) # Subscriber: start subscribe session A s_disc_id_a = s_dut.droid.wifiAwareSubscribe( s_id, autils.create_discovery_config(SERVICE_NAME, type_x[1]), use_id) autils.wait_for_event(s_dut, autils.decorate_event( aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, s_disc_id_a)) # Subscriber: start subscribe session B s_disc_id_b = s_dut.droid.wifiAwareSubscribe( p_id, autils.create_discovery_config(SERVICE_NAME, type_y[1]), use_id) autils.wait_for_event(s_dut, autils.decorate_event( aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, s_disc_id_b)) session_name = {"pub": {p_disc_id_x: "X", p_disc_id_y: "Y"}, "sub": {s_disc_id_a: "A", s_disc_id_b: "B"}} # Subscriber: subscribe session A & B wait for service discovery # Number of results on each session should be exactly 2 results_a = {} for i in range(2): event = autils.wait_for_event(s_dut, autils.decorate_event( aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, s_disc_id_a)) results_a[ bytes(event["data"][ aconsts.SESSION_CB_KEY_SERVICE_SPECIFIC_INFO]).decode('utf-8')] = event autils.fail_on_event(s_dut, autils.decorate_event( aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, s_disc_id_a)) results_b = {} for i in range(2): event = autils.wait_for_event(s_dut, autils.decorate_event( aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, s_disc_id_b)) results_b[ bytes(event["data"][ aconsts.SESSION_CB_KEY_SERVICE_SPECIFIC_INFO]).decode('utf-8')] = event autils.fail_on_event(s_dut, autils.decorate_event( aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, s_disc_id_b)) s_a_peer_id_for_p_x = results_a[X_SERVICE_SSI]["data"][aconsts.SESSION_CB_KEY_PEER_ID] s_a_peer_id_for_p_y = results_a[Y_SERVICE_SSI]["data"][aconsts.SESSION_CB_KEY_PEER_ID] s_b_peer_id_for_p_x = results_b[X_SERVICE_SSI]["data"][aconsts.SESSION_CB_KEY_PEER_ID] s_b_peer_id_for_p_y = results_b[Y_SERVICE_SSI]["data"][aconsts.SESSION_CB_KEY_PEER_ID] # Message exchange between Publisher and Subscribe self.exchange_messages(p_dut, p_disc_id_x, s_dut, s_disc_id_a, s_a_peer_id_for_p_x, session_name) self.exchange_messages(p_dut, p_disc_id_x, s_dut, s_disc_id_b, s_b_peer_id_for_p_x, session_name) self.exchange_messages(p_dut, p_disc_id_y, s_dut, s_disc_id_a, s_a_peer_id_for_p_y, session_name) self.exchange_messages(p_dut, p_disc_id_y, s_dut, s_disc_id_b, s_b_peer_id_for_p_y, session_name) # Check no more messages time.sleep(autils.EVENT_TIMEOUT) autils.verify_no_more_events(p_dut, timeout=0) autils.verify_no_more_events(s_dut, timeout=0) ########################################################## @test_tracker_info(uuid="78d89d63-1cbc-47f6-a8fc-74057fea655e") def test_multiple_concurrent_services_diff_ssi_unsolicited_passive(self): """Multi service test on same service name but different Service Specific Info - Unsolicited publish - Passive subscribe """ self.run_multiple_concurrent_services_same_name_diff_ssi( type_x=[aconsts.PUBLISH_TYPE_UNSOLICITED, aconsts.SUBSCRIBE_TYPE_PASSIVE], type_y=[aconsts.PUBLISH_TYPE_UNSOLICITED, aconsts.SUBSCRIBE_TYPE_PASSIVE]) @test_tracker_info(uuid="5d349491-48e4-4ca1-a8af-7afb44e7bcbc") def test_multiple_concurrent_services_diff_ssi_solicited_active(self): """Multi service test on same service name but different Service Specific Info - Solicited publish - Active subscribe """ self.run_multiple_concurrent_services_same_name_diff_ssi( type_x=[aconsts.PUBLISH_TYPE_SOLICITED, aconsts.SUBSCRIBE_TYPE_ACTIVE], type_y=[aconsts.PUBLISH_TYPE_SOLICITED, aconsts.SUBSCRIBE_TYPE_ACTIVE]) def run_service_discovery_on_service_lost(self, p_type, s_type): """ Validate service lost callback will be receive on subscriber, when publisher stopped publish - p_dut running Publish - s_dut running subscribe - s_dut discover p_dut - p_dut stop publish - s_dut receive service lost callback Args: p_type: Publish discovery type s_type: Subscribe discovery type """ p_dut = self.android_devices[0] p_dut.pretty_name = "Publisher" s_dut = self.android_devices[1] s_dut.pretty_name = "Subscriber" asserts.skip_if(not s_dut.droid.isSdkAtLeastS(), "R build and below do not have onServiceLost API.") # Publisher+Subscriber: attach and wait for confirmation p_id = p_dut.droid.wifiAwareAttach(False) autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED) time.sleep(self.device_startup_offset) s_id = s_dut.droid.wifiAwareAttach(False) autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED) # Publisher: start publish and wait for confirmation p_config = self.create_publish_config( p_dut.aware_capabilities, p_type, self.PAYLOAD_SIZE_TYPICAL, ttl=0, term_ind_on=False, null_match=False) p_disc_id = p_dut.droid.wifiAwarePublish(p_id, p_config) autils.wait_for_event(p_dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED) # Subscriber: start subscribe and wait for confirmation s_config = self.create_subscribe_config( s_dut.aware_capabilities, s_type, self.PAYLOAD_SIZE_TYPICAL, ttl=0, term_ind_on=False, null_match=True) s_disc_id = s_dut.droid.wifiAwareSubscribe(s_id, s_config) autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED) # Subscriber: wait for service discovery discovery_event = autils.wait_for_event( s_dut, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) peer_id_on_sub = discovery_event["data"][ aconsts.SESSION_CB_KEY_PEER_ID] # Publisher+Subscriber: Terminate sessions p_dut.droid.wifiAwareDestroyDiscoverySession(p_disc_id) time.sleep(10) service_lost_event = autils.wait_for_event( s_dut, aconsts.SESSION_CB_ON_SERVICE_LOST) asserts.assert_equal(peer_id_on_sub, service_lost_event["data"][aconsts.SESSION_CB_KEY_PEER_ID]) asserts.assert_equal(aconsts.REASON_PEER_NOT_VISIBLE, service_lost_event["data"][aconsts.SESSION_CB_KEY_LOST_REASON]) s_dut.droid.wifiAwareDestroyDiscoverySession(s_disc_id) @test_tracker_info(uuid="b1894ce3-8692-478b-a96f-db2797e22caa") def test_service_discovery_on_service_lost_unsolicited_passive(self): """ Test service discovery lost with unsolicited publish and passive subscribe """ self.run_service_discovery_on_service_lost(aconsts.PUBLISH_TYPE_UNSOLICITED, aconsts.SUBSCRIBE_TYPE_PASSIVE) @test_tracker_info(uuid="4470d897-223a-4f9f-b21f-4061943137dd") def test_service_discovery_on_service_lost_solicited_active(self): """ Test service discovery lost with solicited publish and active subscribe """ self.run_service_discovery_on_service_lost(aconsts.PUBLISH_TYPE_SOLICITED, aconsts.SUBSCRIBE_TYPE_ACTIVE)