1# Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import logging
6
7from autotest_lib.client.bin import test
8from autotest_lib.client.bin import utils
9from autotest_lib.client.common_lib import error
10
11from autotest_lib.client.cros.cellular import mm1_constants
12from autotest_lib.client.cros.cellular import test_environment
13from autotest_lib.client.cros.networking import cellular_proxy
14from autotest_lib.client.cros.networking import pm_proxy
15from autotest_lib.client.cros.networking import shill_context
16
17SHORT_TIMEOUT = 10
18
19
20class cellular_OutOfCreditsSubscriptionState(test.test):
21    """
22    This test verifies that shill out-of-credits behavior works properly based
23    on the modem subscription state.
24
25    """
26    version = 1
27
28    def _initialize_modem(self, subscription_state):
29        # Simulate an Altair 3100 modem since that modem supports subscription
30        # state information.
31        self.test_env.shill.disable_modem_for_test_setup()
32        # TODO(thieule): Set the modem model using the pseudomodem testing
33        # interface (crbug.com/343258).
34        self.modem.iface_properties.Set(
35                mm1_constants.I_MODEM,
36                mm1_constants.MM_MODEM_PROPERTY_NAME_PLUGIN,
37                'Altair LTE')
38        self.pseudomm.iface_testing.SetSubscriptionState(
39                subscription_state)
40        self.test_env.shill.manager.EnableTechnology(
41                cellular_proxy.CellularProxy.TECHNOLOGY_CELLULAR)
42        # Wait for a registered state.
43        self.modem.wait_for_states([mm1_constants.MM_MODEM_STATE_REGISTERED,
44                                    mm1_constants.MM_MODEM_STATE_CONNECTED])
45
46
47    def _is_out_of_credits(self, cellular_service):
48        properties = cellular_service.GetProperties(utf8_strings=True)
49        return properties[cellular_proxy.CellularProxy.
50                          DEVICE_PROPERTY_OUT_OF_CREDITS]
51
52
53    def _test_provisioned(self):
54        logging.info('Initialize modem with provisioned state')
55        self._initialize_modem(
56                mm1_constants.MM_MODEM_3GPP_SUBSCRIPTION_STATE_PROVISIONED)
57        logging.info('Verify out-of-credits is not set in cellular service')
58        cellular_service = \
59                self.test_env.shill.wait_for_cellular_service_object()
60        if self._is_out_of_credits(cellular_service):
61            error_msg = 'Service marked as out-of-credits when it ' \
62                        'should not be.'
63            logging.error(error_msg)
64            raise error.TestFail(error_msg)
65
66
67    def _test_out_of_credits_at_start(self):
68        logging.info('Initialize modem with out-of-credits state')
69        self._initialize_modem(
70                mm1_constants.MM_MODEM_3GPP_SUBSCRIPTION_STATE_OUT_OF_DATA)
71        logging.info('Verify out-of-credits is set in cellular service')
72        cellular_service = \
73                self.test_env.shill.wait_for_cellular_service_object()
74        if not self._is_out_of_credits(cellular_service):
75            error_msg = 'Service not marked out-of-credits when it ' \
76                        'should be.'
77            logging.error(error_msg)
78            raise error.TestFail(error_msg)
79
80
81    def _test_out_of_credits_while_connected(self):
82        logging.info('Initialize modem with provisioned state')
83        self._initialize_modem(
84                mm1_constants.MM_MODEM_3GPP_SUBSCRIPTION_STATE_PROVISIONED)
85        cellular_service = \
86                self.test_env.shill.wait_for_cellular_service_object()
87        logging.info('Mark modem as out-of-credits')
88        self.pseudomm.iface_testing.SetSubscriptionState(
89                mm1_constants.MM_MODEM_3GPP_SUBSCRIPTION_STATE_OUT_OF_DATA)
90        logging.info('Verify out-of-credits set in cellular service')
91        try:
92            utils.poll_for_condition(
93                    lambda: self._is_out_of_credits(cellular_service),
94                    exception=error.TestFail('Service failed to be marked as '
95                                             'out-of-credits.'),
96                    timeout=SHORT_TIMEOUT)
97        except error.TestFail as e:
98            logging.error(repr(e))
99            raise e
100
101
102    def run_once(self):
103        """Calls by autotest to run this test."""
104        self.test_env = test_environment.CellularPseudoMMTestEnvironment(
105                pseudomm_args=({'family': '3GPP'},))
106        with self.test_env, shill_context.ServiceAutoConnectContext(
107                self.test_env.shill.wait_for_cellular_service_object, False):
108            self.pseudomm = pm_proxy.PseudoMMProxy.get_proxy()
109            self.modem = self.pseudomm.get_modem()
110
111            self._test_provisioned()
112            self._test_out_of_credits_at_start()
113            self._test_out_of_credits_while_connected()
114