Add mulit devices mdns tests
Add tests to verify mdns advertising, discovery, and resolution over a hotspot connection using multiple devices. Bug: 343311941 Test: atest CtsConnectivityMultiDevicesTestCases Change-Id: I9f52a271385cddc12c8f57b188e080ad69651f9f
This commit is contained in:
parent
ac6131b5f1
commit
7d42feb303
6 changed files with 162 additions and 1 deletions
|
|
@ -5,6 +5,7 @@ from mobly import base_test
|
|||
from mobly import test_runner
|
||||
from mobly import utils
|
||||
from mobly.controllers import android_device
|
||||
from utils import mdns_utils
|
||||
from utils import tether_utils
|
||||
from utils.tether_utils import UpstreamType
|
||||
|
||||
|
|
@ -61,6 +62,25 @@ class ConnectivityMultiDevicesTest(base_test.BaseTestClass):
|
|||
self.serverDevice, UpstreamType.CELLULAR
|
||||
)
|
||||
|
||||
def test_mdns_via_hotspot(self):
|
||||
tether_utils.assume_hotspot_test_preconditions(
|
||||
self.serverDevice, self.clientDevice, UpstreamType.NONE
|
||||
)
|
||||
try:
|
||||
# Connectivity of the client verified by asserting the validated capability.
|
||||
tether_utils.setup_hotspot_and_client_for_upstream_type(
|
||||
self.serverDevice, self.clientDevice, UpstreamType.NONE
|
||||
)
|
||||
mdns_utils.register_mdns_service_and_discover_resolve(
|
||||
self.clientDevice, self.serverDevice
|
||||
)
|
||||
finally:
|
||||
mdns_utils.cleanup_mdns_service(
|
||||
self.clientDevice, self.serverDevice
|
||||
)
|
||||
tether_utils.cleanup_tethering_for_upstream_type(
|
||||
self.serverDevice, UpstreamType.NONE
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Take test args
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ android_test_helper_app {
|
|||
],
|
||||
srcs: [
|
||||
"ConnectivityMultiDevicesSnippet.kt",
|
||||
"MdnsMultiDevicesSnippet.kt",
|
||||
],
|
||||
manifest: "AndroidManifest.xml",
|
||||
static_libs: [
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@
|
|||
of a snippet class -->
|
||||
<meta-data
|
||||
android:name="mobly-snippets"
|
||||
android:value="com.google.snippet.connectivity.ConnectivityMultiDevicesSnippet" />
|
||||
android:value="com.google.snippet.connectivity.ConnectivityMultiDevicesSnippet,
|
||||
com.google.snippet.connectivity.MdnsMultiDevicesSnippet" />
|
||||
</application>
|
||||
<!-- Add an instrumentation tag so that the app can be launched through an
|
||||
instrument command. The runner `com.google.android.mobly.snippet.SnippetRunner`
|
||||
|
|
|
|||
92
tests/cts/multidevices/snippet/MdnsMultiDevicesSnippet.kt
Normal file
92
tests/cts/multidevices/snippet/MdnsMultiDevicesSnippet.kt
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright (C) 2024 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.
|
||||
*/
|
||||
|
||||
package com.google.snippet.connectivity
|
||||
|
||||
import android.net.nsd.NsdManager
|
||||
import android.net.nsd.NsdServiceInfo
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import com.android.testutils.NsdDiscoveryRecord
|
||||
import com.android.testutils.NsdDiscoveryRecord.DiscoveryEvent.DiscoveryStopped
|
||||
import com.android.testutils.NsdRegistrationRecord
|
||||
import com.android.testutils.NsdRegistrationRecord.RegistrationEvent.ServiceRegistered
|
||||
import com.android.testutils.NsdRegistrationRecord.RegistrationEvent.ServiceUnregistered
|
||||
import com.android.testutils.NsdResolveRecord
|
||||
import com.android.testutils.NsdResolveRecord.ResolveEvent.ServiceResolved
|
||||
import com.google.android.mobly.snippet.Snippet
|
||||
import com.google.android.mobly.snippet.rpc.Rpc
|
||||
import kotlin.test.assertEquals
|
||||
import org.junit.Assert.assertArrayEquals
|
||||
|
||||
private const val SERVICE_NAME = "MultiDevicesTest"
|
||||
private const val SERVICE_TYPE = "_multi_devices._tcp"
|
||||
private const val SERVICE_ATTRIBUTES_KEY = "key"
|
||||
private const val SERVICE_ATTRIBUTES_VALUE = "value"
|
||||
private const val SERVICE_PORT = 12345
|
||||
private const val REGISTRATION_TIMEOUT_MS = 10_000L
|
||||
|
||||
class MdnsMultiDevicesSnippet : Snippet {
|
||||
private val context = InstrumentationRegistry.getInstrumentation().getTargetContext()
|
||||
private val nsdManager = context.getSystemService(NsdManager::class.java)!!
|
||||
private val registrationRecord = NsdRegistrationRecord()
|
||||
private val discoveryRecord = NsdDiscoveryRecord()
|
||||
private val resolveRecord = NsdResolveRecord()
|
||||
|
||||
@Rpc(description = "Register a mDns service")
|
||||
fun registerMDnsService() {
|
||||
val info = NsdServiceInfo()
|
||||
info.setServiceName(SERVICE_NAME)
|
||||
info.setServiceType(SERVICE_TYPE)
|
||||
info.setPort(SERVICE_PORT)
|
||||
info.setAttribute(SERVICE_ATTRIBUTES_KEY, SERVICE_ATTRIBUTES_VALUE)
|
||||
nsdManager.registerService(info, NsdManager.PROTOCOL_DNS_SD, registrationRecord)
|
||||
registrationRecord.expectCallback<ServiceRegistered>(REGISTRATION_TIMEOUT_MS)
|
||||
}
|
||||
|
||||
@Rpc(description = "Unregister a mDns service")
|
||||
fun unregisterMDnsService() {
|
||||
nsdManager.unregisterService(registrationRecord)
|
||||
registrationRecord.expectCallback<ServiceUnregistered>()
|
||||
}
|
||||
|
||||
@Rpc(description = "Ensure the discovery and resolution of the mDNS service")
|
||||
// Suppress the warning, as the NsdManager#resolveService() method is deprecated.
|
||||
@Suppress("DEPRECATION")
|
||||
fun ensureMDnsServiceDiscoveryAndResolution() {
|
||||
// Discover a mDns service that matches the test service
|
||||
nsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, discoveryRecord)
|
||||
val info = discoveryRecord.waitForServiceDiscovered(SERVICE_NAME, SERVICE_TYPE)
|
||||
// Resolve the retrieved mDns service.
|
||||
nsdManager.resolveService(info, resolveRecord)
|
||||
val serviceResolved = resolveRecord.expectCallbackEventually<ServiceResolved>()
|
||||
serviceResolved.serviceInfo.let {
|
||||
assertEquals(SERVICE_NAME, it.serviceName)
|
||||
assertEquals(".$SERVICE_TYPE", it.serviceType)
|
||||
assertEquals(SERVICE_PORT, it.port)
|
||||
assertEquals(1, it.attributes.size)
|
||||
assertArrayEquals(
|
||||
SERVICE_ATTRIBUTES_VALUE.encodeToByteArray(),
|
||||
it.attributes[SERVICE_ATTRIBUTES_KEY]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Rpc(description = "Stop discovery")
|
||||
fun stopMDnsServiceDiscovery() {
|
||||
nsdManager.stopServiceDiscovery(discoveryRecord)
|
||||
discoveryRecord.expectCallbackEventually<DiscoveryStopped>()
|
||||
}
|
||||
}
|
||||
42
tests/cts/multidevices/utils/mdns_utils.py
Normal file
42
tests/cts/multidevices/utils/mdns_utils.py
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
# Copyright (C) 2024 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.
|
||||
|
||||
from mobly.controllers import android_device
|
||||
|
||||
|
||||
def register_mdns_service_and_discover_resolve(
|
||||
advertising_device: android_device, discovery_device: android_device
|
||||
) -> None:
|
||||
"""Test mdns advertising, discovery and resolution
|
||||
|
||||
One device registers an mDNS service, and another device discovers and
|
||||
resolves that service.
|
||||
"""
|
||||
advertising = advertising_device.connectivity_multi_devices_snippet
|
||||
discovery = discovery_device.connectivity_multi_devices_snippet
|
||||
|
||||
# Register a mDns service
|
||||
advertising.registerMDnsService()
|
||||
|
||||
# Ensure the discovery and resolution of the mDNS service
|
||||
discovery.ensureMDnsServiceDiscoveryAndResolution()
|
||||
|
||||
|
||||
def cleanup_mdns_service(
|
||||
advertising_device: android_device, discovery_device: android_device
|
||||
) -> None:
|
||||
# Unregister the mDns service
|
||||
advertising_device.connectivity_multi_devices_snippet.unregisterMDnsService()
|
||||
# Stop discovery
|
||||
discovery_device.connectivity_multi_devices_snippet.stopMDnsServiceDiscovery()
|
||||
|
|
@ -20,6 +20,7 @@ from mobly.controllers import android_device
|
|||
|
||||
|
||||
class UpstreamType:
|
||||
NONE = 0
|
||||
CELLULAR = 1
|
||||
WIFI = 2
|
||||
|
||||
|
|
@ -56,6 +57,8 @@ def assume_hotspot_test_preconditions(
|
|||
not server.isStaApConcurrencySupported(),
|
||||
"Server requires Wifi AP + STA concurrency",
|
||||
)
|
||||
elif upstream_type == UpstreamType.NONE:
|
||||
pass
|
||||
else:
|
||||
raise ValueError(f"Invalid upstream type: {upstream_type}")
|
||||
|
||||
|
|
@ -78,6 +81,8 @@ def setup_hotspot_and_client_for_upstream_type(
|
|||
server.requestCellularAndEnsureDefault()
|
||||
elif upstream_type == UpstreamType.WIFI:
|
||||
server.ensureWifiIsDefault()
|
||||
elif upstream_type == UpstreamType.NONE:
|
||||
pass
|
||||
else:
|
||||
raise ValueError(f"Invalid upstream type: {upstream_type}")
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue