1#
2#   Copyright 2022 - The Android Open Source Project
3#
4#   Licensed under the Apache License, Version 2.0 (the "License");
5#   you may not use this file except in compliance with the License.
6#   You may obtain a copy of the License at
7#
8#       http://www.apache.org/licenses/LICENSE-2.0
9#
10#   Unless required by applicable law or agreed to in writing, software
11#   distributed under the License is distributed on an "AS IS" BASIS,
12#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13#   See the License for the specific language governing permissions and
14#   limitations under the License.
15
16import threading
17import time
18
19from acts import asserts
20from acts import base_test
21from acts import utils
22from acts.controllers import adb
23from acts.controllers.adb_lib.error import AdbError
24from acts.controllers.ap_lib import hostapd_constants
25from acts.test_decorators import test_tracker_info
26from acts_contrib.test_utils.net import connectivity_const as cconst
27from acts_contrib.test_utils.net import connectivity_test_utils as cutils
28from acts_contrib.test_utils.net import net_test_utils as nutils
29from acts_contrib.test_utils.net.net_test_utils import start_tcpdump
30from acts_contrib.test_utils.net.net_test_utils import stop_tcpdump
31from acts_contrib.test_utils.tel import tel_test_utils as ttutils
32from acts_contrib.test_utils.tel.tel_test_utils import get_operator_name
33from acts_contrib.test_utils.tel.tel_data_utils import http_file_download_by_chrome
34from acts_contrib.test_utils.wifi import wifi_test_utils as wutils
35import queue
36from queue import Empty
37
38
39conn_test_class = "com.android.tests.connectivity.uid.ConnectivityTestActivity"
40android_os_class = "com.quicinc.cne.CNEService.CNEServiceApp"
41instr_cmd = ("am instrument -w -e command grant-all "
42             "com.android.permissionutils/.PermissionInstrumentation")
43
44HOUR_IN_MILLIS = 1000 * 60 * 60
45BYTE_TO_MB_ANDROID = 1000.0 * 1000.0
46BYTE_TO_MB = 1024.0 * 1024.0
47DOWNLOAD_PATH = "/sdcard/download/"
48DATA_USG_ERR = 2.2
49DATA_ERR = 0.2
50TIMEOUT = 2 * 60
51INC_DATA = 10
52AP_PASSPHRASE_LENGTH_2G = hostapd_constants.AP_PASSPHRASE_LENGTH_2G
53AP_SSID_LENGTH_2G = hostapd_constants.AP_SSID_LENGTH_2G
54RETRY_SLEEP = 3
55WIFI_SLEEP = 180
56
57
58class DataUsageTest(base_test.BaseTestClass):
59    """Data usage tests.
60
61    Requirements:
62       Two Pixel devices - one device with TMO and other with VZW SIM
63       WiFi network - Wifi network to test wifi data usage
64    """
65
66    def __init__(self, controllers):
67        base_test.BaseTestClass.__init__(self, controllers)
68
69    def setup_class(self):
70        """Setup devices for tests and unpack params."""
71
72        # unpack user params
73        req_params = ("wifi_network",
74                      "file_size",
75                      "download_file_ipv4",
76                      "download_file_ipv6",
77                      "dbs_supported_models")
78        self.unpack_userparams(req_params)
79        self.file_path = DOWNLOAD_PATH + self.download_file_ipv4.split("/")[-1]
80        self.file_size = float(self.file_size)
81
82        for ad in self.android_devices:
83            self.log.info("Operator on %s is %s" % \
84                          (ad.serial, get_operator_name(self.log, ad)))
85            ad.reboot()
86            nutils.verify_lte_data_and_tethering_supported(ad)
87            nutils.set_chrome_browser_permissions(ad)
88            cutils.set_private_dns(ad, cconst.PRIVATE_DNS_MODE_OFF)
89            try:
90                ad.adb.shell(instr_cmd)
91            except AdbError:
92                self.log.warn("cmd %s failed on %s" % (instr_cmd, ad.serial))
93        self.tcpdumps = []
94        self.hs_enabled = []
95
96    def setup_test(self):
97        for ad in self.android_devices:
98            self.tcpdumps.append(start_tcpdump(ad, self.test_name))
99            ad.droid.wakeLockAcquireBright()
100            ad.droid.wakeUpNow()
101
102    def teardown_test(self):
103        for ad in self.hs_enabled:
104            try:
105                wutils.stop_wifi_tethering(ad)
106            except Exception as e:
107              self.log.warn("Failed to stop wifi tethering: %s" % e)
108        self.hs_enabled = []
109        for i in range(len(self.android_devices)):
110            ad = self.android_devices[i]
111            stop_tcpdump(ad, self.tcpdumps[i], self.test_name)
112            wutils.reset_wifi(ad)
113            sub_id = str(ad.droid.telephonyGetSubscriberId())
114            ad.droid.connectivityFactoryResetNetworkPolicies(sub_id)
115            ad.droid.telephonyToggleDataConnection(True)
116            ad.droid.wakeLockRelease()
117            ad.droid.goToSleepNow()
118        self.tcpdumps = []
119
120    def teardown_class(self):
121        for ad in self.android_devices:
122            cutils.set_private_dns(ad, cconst.PRIVATE_DNS_MODE_OPPORTUNISTIC)
123
124    def on_fail(self, test_name, begin_time):
125        for ad in self.android_devices:
126            ad.take_bug_report(test_name, begin_time)
127
128    ### Helper functions
129
130    def _download_data_through_app(self, ad, file_link):
131        """Download data through app on DUT.
132
133        Args:
134            ad: DUT to download the file on
135            file_link: http link of the file to download
136
137        Returns:
138            True if file download is successful, False if not
139        """
140        intent = ad.droid.createIntentForClassName(conn_test_class)
141        json_obj = {"url": file_link}
142        ad.droid.launchForResultWithIntent(intent, json_obj)
143        download_status = False
144        end_time = time.time() + TIMEOUT
145        while time.time() < end_time:
146            download_status = ttutils._check_file_existence(
147                ad, self.file_path, self.file_size * BYTE_TO_MB)
148            if download_status:
149                self.log.info("Delete file: %s", self.file_path)
150                ad.adb.shell("rm %s" % self.file_path, ignore_status=True)
151                break
152            time.sleep(RETRY_SLEEP*2)  # wait to check if download is complete
153        return download_status
154
155    def _get_total_data_usage_for_device(self, ad, conn_type):
156        """Get total data usage in MB for device.
157
158        Args:
159            ad: android device object
160            conn_type: MOBILE/WIFI data usage
161
162        Returns:
163            Data usage in MB
164        """
165        sub_id = str(ad.droid.telephonyGetSubscriberId())
166        end_time = int(time.time() * 1000) + 2 * HOUR_IN_MILLIS
167        data_usage = ad.droid.connectivityQuerySummaryForDevice(
168            conn_type, sub_id, 0, end_time)
169        data_usage /= BYTE_TO_MB_ANDROID
170        self.log.info("Total data usage is: %s" % data_usage)
171        return data_usage
172
173    def _get_data_usage_for_uid_rx(self, ad, conn_type, uid):
174        """Get data usage for UID in Rx Bytes.
175
176        Args:
177            ad: DUT to get data usage from
178            conn_type: MOBILE/WIFI data usage
179            uid: UID of the app
180
181        Returns:
182            Data usage in MB
183        """
184        if conn_type == cconst.TYPE_WIFI:
185            subscriber_id = None
186        else:
187            subscriber_id = ad.droid.telephonyGetSubscriberId()
188        end_time = int(time.time() * 1000) + 2 * HOUR_IN_MILLIS
189        data_usage = ad.droid.connectivityQueryDetailsForUidRxBytes(
190            conn_type, subscriber_id, 0, end_time, uid)
191        return data_usage/BYTE_TO_MB_ANDROID
192
193    def _get_data_usage_for_device_rx(self, ad, conn_type):
194        """Get total data usage in rx bytes for device.
195
196        Args:
197            ad: DUT to get data usage from
198            conn_type: MOBILE/WIFI data usage
199
200        Returns:
201            Data usage in MB
202        """
203        if conn_type == cconst.TYPE_WIFI:
204            subscriber_id = None
205        else:
206            subscriber_id = ad.droid.telephonyGetSubscriberId()
207        end_time = int(time.time() * 1000) + 2 * HOUR_IN_MILLIS
208        data_usage = ad.droid.connectivityQuerySummaryForDeviceRxBytes(
209            conn_type, subscriber_id, 0, end_time)
210        return data_usage/BYTE_TO_MB_ANDROID
211
212    def _get_data_usage(self, ad, conn_type):
213        """Get data usage.
214
215        Args:
216            ad: DUT to get data usage from
217            conn_type: MOBILE/WIFI data usage
218
219        Returns:
220            Tuple of Android Os app, Conn UID app, Total data usages
221        """
222        android_os_uid = ad.droid.getUidForPackage(android_os_class)
223        conn_test_uid = ad.droid.getUidForPackage(conn_test_class)
224        aos = self._get_data_usage_for_uid_rx(ad, conn_type, android_os_uid)
225        app = self._get_data_usage_for_uid_rx(ad, conn_type, conn_test_uid)
226        tot = self._get_data_usage_for_device_rx(ad, conn_type)
227        self.log.info("Android Os data usage: %s" % aos)
228        self.log.info("Conn UID Test data usage: %s" % app)
229        self.log.info("Total data usage: %s" % tot)
230        return (aos, app, tot)
231
232    def _listen_for_network_callback(self, ad, event, q):
233        """Verify network callback for data usage.
234
235        Args:
236            ad: DUT to get the network callback for
237            event: Network callback event
238            q: queue object
239
240        Returns:
241            True: if the expected network callback found, False if not
242        """
243        key = ad.droid.connectivityRegisterDefaultNetworkCallback()
244        ad.droid.connectivityNetworkCallbackStartListeningForEvent(key, event)
245
246        curr_time = time.time()
247        status = False
248        while time.time() < curr_time + TIMEOUT:
249            try:
250                nc_event = ad.ed.pop_event("NetworkCallback")
251                self.log.info("Received: %s" %
252                              nc_event["data"]["networkCallbackEvent"])
253                if nc_event["data"]["networkCallbackEvent"] == event:
254                    status = True
255                    break
256            except Empty:
257                pass
258
259        ad.droid.connectivityNetworkCallbackStopListeningForEvent(key, event)
260        ad.droid.connectivityUnregisterNetworkCallback(key)
261        q.put(status)
262
263    def _test_data_usage_downlink(self,
264                                  dut_a,
265                                  dut_b,
266                                  file_link,
267                                  data_usage,
268                                  tethering=False,
269                                  connect_wifi=False,
270                                  app_inc=True):
271        """Verify data usage.
272
273        Steps:
274            1. Get the current data usage of ConnUIDTest and Android OS apps
275            2. DUT is on LTE data (on wifi if connect_wifi is True)
276            3. Download file of size xMB through ConnUIDTest app
277            4. Verify that data usage of Android OS app did not change
278            5. Verify that data usage of ConnUIDTest app increased by ~xMB
279            6. Verify that data usage of device also increased by ~xMB
280
281        Args:
282            dut_a: DUT on which data usage need to be verified
283            dut_b: DUT on which data is downloaded
284            file_link: Link used to download data
285            data_usage: specifies if MOBILE or WIFI data is calculated
286            tethering: if True, enable hotspot on dut_a and connect dut_b to it
287            connect_wifi: if True, connect dut_a to a wifi network
288            app_inc: if True, verify app data usage on dut_a is increased
289        """
290        if connect_wifi:
291            dut_a.droid.telephonyToggleDataConnection(False)
292            wutils.start_wifi_connection_scan_and_ensure_network_found(
293                dut_a, self.wifi_network["SSID"])
294            wutils.wifi_connect(dut_a, self.wifi_network)
295            # sleep for some time after connecting to wifi. some apps use wifi
296            # data when connected initially. waiting after connecting to wifi
297            # ensures correct wifi data usage calculation
298            time.sleep(WIFI_SLEEP)
299
300        if tethering:
301            ssid = "hs_%s" % utils.rand_ascii_str(AP_SSID_LENGTH_2G)
302            pwd = utils.rand_ascii_str(AP_PASSPHRASE_LENGTH_2G)
303            network = {wutils.WifiEnums.SSID_KEY: ssid,
304                       wutils.WifiEnums.PWD_KEY: pwd}
305            dut_b.droid.telephonyToggleDataConnection(False)
306            wutils.start_wifi_tethering(dut_a,
307                                        network[wutils.WifiEnums.SSID_KEY],
308                                        network[wutils.WifiEnums.PWD_KEY])
309            self.hs_enabled.append(dut_a)
310            wutils.start_wifi_connection_scan_and_ensure_network_found(
311                dut_b, network[wutils.WifiEnums.SSID_KEY])
312            wutils.wifi_connect(dut_b, network)
313            # sleep for some time after connecting to wifi. though wifi hotspot
314            # is metered, some apps would still use wifi data when connected
315            # initially. this ensures correct wifi data usage calculation
316            time.sleep(WIFI_SLEEP)
317
318        # get pre data usage
319        (aos_pre, app_pre, total_pre) = self._get_data_usage(dut_a, data_usage)
320
321        # download file through app
322        status = self._download_data_through_app(dut_b, file_link)
323        asserts.assert_true(status, "Failed to download file: %s" % file_link)
324
325        # get new data usage
326        aos_exp = DATA_ERR
327        app_exp = self.file_size + DATA_USG_ERR
328        file_size = self.file_size
329        if not app_inc:
330            app_exp = DATA_ERR
331            file_size = 0
332        total_exp = self.file_size + DATA_USG_ERR
333
334        # somtimes data usage is not increased immediately.
335        # re-tries until the data usage is closed to expected value.
336        curr_time = time.time()
337        while time.time() < curr_time + TIMEOUT:
338            (aos_pst, app_pst, total_pst) = self._get_data_usage(dut_a,
339                                                                 data_usage)
340            if total_pst - total_pre >= self.file_size and \
341                app_pst - app_pre >= file_size:
342                  # wait for some time to verify that data doesn't increase
343                  time.sleep(RETRY_SLEEP*2)
344                  break
345            time.sleep(RETRY_SLEEP)  # wait before retry
346        (aos_pst, app_pst, total_pst) = self._get_data_usage(dut_a, data_usage)
347
348        # verify data usage
349        aos_diff = aos_pst - aos_pre
350        app_diff = app_pst - app_pre
351        total_diff = total_pst - total_pre
352        self.log.info("Usage of Android OS increased: %sMB, expected: %sMB" % \
353                      (aos_diff, aos_exp))
354        self.log.info("Usage of ConnUID app increased: %sMB, expected: %sMB" % \
355                      (app_diff, app_exp))
356        self.log.info("Usage on the device increased: %sMB, expected: %sMB" % \
357                      (total_diff, total_exp))
358
359        asserts.assert_true(
360            (aos_diff < aos_exp) and (file_size <= app_diff < app_exp) and \
361                (self.file_size <= total_diff < total_exp),
362            "Incorrect data usage count")
363
364    def _test_data_usage_limit_downlink(self,
365                                        dut_a,
366                                        dut_b,
367                                        file_link,
368                                        data_usage,
369                                        tethering=False):
370        """Verify data usage limit reached.
371
372        Steps:
373            1. Set the data usage limit to current data usage + 10MB
374            2. If tested for tethered device, start wifi hotspot and
375               connect DUT to it.
376            3. If tested for tethered device, download 20MB data from
377               tethered device else download on the same DUT
378            4. Verify file download stops and data limit reached
379
380        Args:
381            dut_a: DUT on which data usage limit needs to be verified
382            dut_b: DUT on which data needs to be downloaded
383            file_link: specifies if the link is IPv4 or IPv6
384            data_usage: specifies if MOBILE or WIFI data usage
385            tethering: if wifi hotspot should be enabled on dut_a
386        """
387        sub_id = str(dut_a.droid.telephonyGetSubscriberId())
388
389        # enable hotspot and connect dut_b to it.
390        if tethering:
391            ssid = "hs_%s" % utils.rand_ascii_str(AP_SSID_LENGTH_2G)
392            pwd = utils.rand_ascii_str(AP_PASSPHRASE_LENGTH_2G)
393            network = {wutils.WifiEnums.SSID_KEY: ssid,
394                       wutils.WifiEnums.PWD_KEY: pwd}
395            dut_b.droid.telephonyToggleDataConnection(False)
396            wutils.start_wifi_tethering(dut_a,
397                                        network[wutils.WifiEnums.SSID_KEY],
398                                        network[wutils.WifiEnums.PWD_KEY])
399            self.hs_enabled.append(dut_a)
400            wutils.start_wifi_connection_scan_and_ensure_network_found(
401                dut_b, network[wutils.WifiEnums.SSID_KEY])
402            wutils.wifi_connect(dut_b, network)
403
404        # get pre mobile data usage
405        total_pre = self._get_total_data_usage_for_device(dut_a, data_usage)
406
407        # set data usage limit to current usage limit + 10MB
408        self.log.info("Set data usage limit to %sMB" % (total_pre + INC_DATA))
409        dut_a.droid.connectivitySetDataUsageLimit(
410            sub_id, int((total_pre + INC_DATA) * BYTE_TO_MB_ANDROID))
411
412        # download file on dut_b and look for BlockedStatusChanged callback
413        q = queue.Queue()
414        t = threading.Thread(target=self._listen_for_network_callback,
415                             args=(dut_a, "BlockedStatusChanged", q))
416        t.daemon = True
417        t.start()
418        status = http_file_download_by_chrome(
419            dut_b, file_link, self.file_size, True, TIMEOUT)
420        t.join()
421        cb_res = q.get()
422
423        # verify file download fails and expected callback is recevied
424        asserts.assert_true(cb_res,
425                            "Failed to verify blocked status network callback")
426        asserts.assert_true(not status,
427                            "File download successful. Expected to fail")
428
429    ### Test Cases
430
431    @test_tracker_info(uuid="b2d9b36c-3a1c-47ca-a9c1-755450abb20c")
432    def test_mobile_data_usage_downlink_ipv4_tmo(self):
433        """Verify mobile data usage over IPv4 and TMO carrier."""
434        self._test_data_usage_downlink(self.android_devices[0],
435                                       self.android_devices[0],
436                                       self.download_file_ipv4,
437                                       cconst.TYPE_MOBILE)
438
439    @test_tracker_info(uuid="fbbb58ed-d573-4bbd-bd5d-0bc540507896")
440    def test_mobile_data_usage_downlink_ipv6_tmo(self):
441        """Verify mobile data usage over IPv6 and TMO carrier."""
442        self._test_data_usage_downlink(self.android_devices[0],
443                                       self.android_devices[0],
444                                       self.download_file_ipv6,
445                                       cconst.TYPE_MOBILE)
446
447    @test_tracker_info(uuid="6562d626-2271-4d93-96c0-f33138635330")
448    def test_mobile_data_usage_downlink_ipv4_vzw(self):
449        """Verify mobile data usage over IPv4 and VZW carrier."""
450        self._test_data_usage_downlink(self.android_devices[1],
451                                       self.android_devices[1],
452                                       self.download_file_ipv4,
453                                       cconst.TYPE_MOBILE)
454
455    @test_tracker_info(uuid="2edf94cf-d937-459a-a7e4-2c679803c4d3")
456    def test_mobile_data_usage_downlink_ipv6_vzw(self):
457        """Verify mobile data usage over IPv6 and VZW carrier."""
458        self._test_data_usage_downlink(self.android_devices[1],
459                                       self.android_devices[1],
460                                       self.download_file_ipv6,
461                                       cconst.TYPE_MOBILE)
462
463    @test_tracker_info(uuid="fe1390e5-635c-49a9-b050-032e66f52f40")
464    def test_wifi_tethering_mobile_data_usage_downlink_ipv4_tmo(self):
465        """Verify mobile data usage with tethered device over IPv4 and TMO."""
466        self._test_data_usage_downlink(self.android_devices[0],
467                                       self.android_devices[1],
468                                       self.download_file_ipv4,
469                                       cconst.TYPE_MOBILE,
470                                       True,
471                                       False,
472                                       False)
473
474    @test_tracker_info(uuid="d7fde6b2-6672-484a-a2fd-47858f5a163f")
475    def test_wifi_tethering_mobile_data_usage_downlink_ipv6_tmo(self):
476        """Verify mobile data usage with tethered device over IPv6 and TMO."""
477        self._test_data_usage_downlink(self.android_devices[0],
478                                       self.android_devices[1],
479                                       self.download_file_ipv6,
480                                       cconst.TYPE_MOBILE,
481                                       True,
482                                       False,
483                                       False)
484
485    @test_tracker_info(uuid="6285ef69-37a8-4069-8cb2-21dc266a57c3")
486    def test_wifi_tethering_mobile_data_usage_downlink_ipv4_vzw(self):
487        """Verify mobile data usage with tethered device over IPv4 and VZW."""
488        self._test_data_usage_downlink(self.android_devices[1],
489                                       self.android_devices[0],
490                                       self.download_file_ipv4,
491                                       cconst.TYPE_MOBILE,
492                                       True,
493                                       False,
494                                       False)
495
496    @test_tracker_info(uuid="565fc7e3-d7cf-43cc-8982-4f17999cf579")
497    def test_wifi_tethering_mobile_data_usage_downlink_ipv6_vzw(self):
498        """Verify mobile data usage with tethered device over IPv6 and VZW."""
499        self._test_data_usage_downlink(self.android_devices[1],
500                                       self.android_devices[0],
501                                       self.download_file_ipv6,
502                                       cconst.TYPE_MOBILE,
503                                       True,
504                                       False,
505                                       False)
506
507    @test_tracker_info(uuid="72ddb42a-5942-4a6a-8b20-2181c41b2765")
508    def test_wifi_data_usage_downlink_ipv4(self):
509        """Verify wifi data usage over IPv4."""
510        self._test_data_usage_downlink(self.android_devices[0],
511                                       self.android_devices[0],
512                                       self.download_file_ipv4,
513                                       cconst.TYPE_WIFI,
514                                       False,
515                                       True,
516                                       True)
517
518    @test_tracker_info(uuid="76b316f5-2946-4757-b5d6-62a8b1fd627e")
519    def test_wifi_data_usage_downlink_ipv6(self):
520        """Verify wifi data usage over IPv6."""
521        self._test_data_usage_downlink(self.android_devices[0],
522                                       self.android_devices[0],
523                                       self.download_file_ipv6,
524                                       cconst.TYPE_WIFI,
525                                       False,
526                                       True,
527                                       True)
528
529    @test_tracker_info(uuid="4be5f2d4-9bc6-4190-813e-044f00d94aa6")
530    def test_wifi_tethering_wifi_data_usage_downlink_ipv4(self):
531        """Verify wifi data usage with tethered device over IPv4."""
532        asserts.skip_if(
533            self.android_devices[0].model not in self.dbs_supported_models,
534            "Device %s does not support dual interfaces." %
535            self.android_devices[0].model)
536        self._test_data_usage_downlink(self.android_devices[0],
537                                       self.android_devices[1],
538                                       self.download_file_ipv4,
539                                       cconst.TYPE_WIFI,
540                                       True,
541                                       True,
542                                       False)
543
544    @test_tracker_info(uuid="ac4750fd-20d9-451d-a85b-79fdbaa7da97")
545    def test_data_usage_limit_downlink_ipv4_tmo(self):
546        """Verify data limit for TMO with IPv4 link."""
547        self._test_data_usage_limit_downlink(self.android_devices[0],
548                                             self.android_devices[0],
549                                             self.download_file_ipv4,
550                                             cconst.TYPE_MOBILE)
551
552    @test_tracker_info(uuid="6598732e-f4d3-40c7-a73b-e89bb3d196c5")
553    def test_data_usage_limit_downlink_ipv6_tmo(self):
554        """Verify data limit for TMO with IPv6 link."""
555        self._test_data_usage_limit_downlink(self.android_devices[0],
556                                             self.android_devices[0],
557                                             self.download_file_ipv6,
558                                             cconst.TYPE_MOBILE)
559
560    @test_tracker_info(uuid="d1ef0405-cf58-4141-94c7-cfa0c9d14438")
561    def test_data_usage_limit_downlink_ipv4_vzw(self):
562        """Verify data limit for VZW with IPv4 link."""
563        self._test_data_usage_limit_downlink(self.android_devices[1],
564                                             self.android_devices[1],
565                                             self.download_file_ipv4,
566                                             cconst.TYPE_MOBILE)
567
568    @test_tracker_info(uuid="18d169d9-fc4f-4782-8f5f-fc96b8976d03")
569    def test_data_usage_limit_downlink_ipv6_vzw(self):
570        """Verify data limit for VZW with IPv6 link."""
571        self._test_data_usage_limit_downlink(self.android_devices[1],
572                                             self.android_devices[1],
573                                             self.download_file_ipv6,
574                                             cconst.TYPE_MOBILE)
575
576    @test_tracker_info(uuid="7c9ab330-9645-4030-bb1e-dcce126944a2")
577    def test_wifi_tethering_data_usage_limit_downlink_ipv4_tmo(self):
578        """Verify data limit for TMO from tethered device with IPv4 link."""
579        self._test_data_usage_limit_downlink(self.android_devices[0],
580                                             self.android_devices[1],
581                                             self.download_file_ipv4,
582                                             cconst.TYPE_MOBILE,
583                                             True)
584
585    @test_tracker_info(uuid="1cafdaf7-a41e-4d19-b08a-ae094d796426")
586    def test_wifi_tethering_data_usage_limit_downlink_ipv6_tmo(self):
587        """Verify data limit for TMO from tethered device with IPv6 link."""
588        self._test_data_usage_limit_downlink(self.android_devices[0],
589                                             self.android_devices[1],
590                                             self.download_file_ipv6,
591                                             cconst.TYPE_MOBILE,
592                                             True)
593
594    @test_tracker_info(uuid="bd5a8f93-4e2f-474d-a01d-4bb5117d5350")
595    def test_wifi_tethering_data_usage_limit_downlink_ipv4_vzw(self):
596        """Verify data limit for VZW from tethered device with IPv4 link."""
597        self._test_data_usage_limit_downlink(self.android_devices[1],
598                                             self.android_devices[0],
599                                             self.download_file_ipv4,
600                                             cconst.TYPE_MOBILE,
601                                             True)
602
603    @test_tracker_info(uuid="ec082fe5-6af1-425e-ace6-4726930bf62f")
604    def test_wifi_tethering_data_usage_limit_downlink_ipv6_vzw(self):
605        """Verify data limit for VZW from tethered device with IPv6 link."""
606        self._test_data_usage_limit_downlink(self.android_devices[1],
607                                             self.android_devices[0],
608                                             self.download_file_ipv6,
609                                             cconst.TYPE_MOBILE,
610                                             True)
611