xref: /aosp_15_r20/external/autotest/client/cros/cellular/hermes_utils.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
1*9c5db199SXin Li# Lint as: python2, python3
2*9c5db199SXin Li# Copyright 2021 The Chromium OS Authors. All rights reserved.
3*9c5db199SXin Li# Use of this source code is governed by a BSD-style license that can be
4*9c5db199SXin Li# found in the LICENSE file.
5*9c5db199SXin Li
6*9c5db199SXin Liimport dbus
7*9c5db199SXin Liimport logging
8*9c5db199SXin Liimport random
9*9c5db199SXin Li
10*9c5db199SXin Lifrom autotest_lib.client.common_lib import error
11*9c5db199SXin Lifrom autotest_lib.client.cros.cellular import hermes_constants
12*9c5db199SXin Lifrom autotest_lib.client.cros.networking import hermes_proxy
13*9c5db199SXin Lifrom autotest_lib.client.cros.networking import mm1_proxy
14*9c5db199SXin Li
15*9c5db199SXin Li# Helper functions
16*9c5db199SXin Lidef connect_to_hermes():
17*9c5db199SXin Li    """
18*9c5db199SXin Li    Attempts to connect to a DBus object.
19*9c5db199SXin Li
20*9c5db199SXin Li    @raise: error.TestFail if connection fails.
21*9c5db199SXin Li
22*9c5db199SXin Li    """
23*9c5db199SXin Li    hermes_manager = 'None'
24*9c5db199SXin Li    try:
25*9c5db199SXin Li        hermes_manager = \
26*9c5db199SXin Li            hermes_proxy.HermesManagerProxy().get_hermes_manager()
27*9c5db199SXin Li    except dbus.DBusException as e:
28*9c5db199SXin Li        logging.error('get_hermes_manager error:%s', e)
29*9c5db199SXin Li        raise error.TestFail('Connect to Hermes failed')
30*9c5db199SXin Li    if hermes_manager is 'None':
31*9c5db199SXin Li        raise error.TestFail('Could not get connection to Hermes')
32*9c5db199SXin Li    return hermes_manager
33*9c5db199SXin Li
34*9c5db199SXin Lidef request_installed_profiles(euicc_path, hermes_manager):
35*9c5db199SXin Li    """
36*9c5db199SXin Li    Check euicc at given path
37*9c5db199SXin Li
38*9c5db199SXin Li    @param euicc_path: path of the sim given
39*9c5db199SXin Li    @return a dict of profiles objects. Returns None if no profile is found
40*9c5db199SXin Li    @raise: error.TestFail if no euicc matching given path
41*9c5db199SXin Li
42*9c5db199SXin Li    """
43*9c5db199SXin Li    euicc = hermes_manager.get_euicc(euicc_path)
44*9c5db199SXin Li    if not euicc:
45*9c5db199SXin Li        raise error.TestFail('No euicc found at:', euicc_path)
46*9c5db199SXin Li
47*9c5db199SXin Li    euicc.request_installed_profiles()
48*9c5db199SXin Li    installed_profiles = euicc.get_installed_profiles()
49*9c5db199SXin Li    if not installed_profiles:
50*9c5db199SXin Li        logging.info('No installed profiles on euicc:%s', euicc_path)
51*9c5db199SXin Li    return euicc, installed_profiles
52*9c5db199SXin Li
53*9c5db199SXin Lidef install_profile(euicc_path, hermes_manager, is_prod_ci):
54*9c5db199SXin Li    """
55*9c5db199SXin Li    Install a profile on the euicc at euicc_path.
56*9c5db199SXin Li
57*9c5db199SXin Li    @param euicc_path: esim path based on testci/prodci
58*9c5db199SXin Li    @param hermes_manager: hermes manager object
59*9c5db199SXin Li    @param is_prod_ci: true if it is prodci test and false for testci
60*9c5db199SXin Li    @return iccid: iccid of the installed profile or None
61*9c5db199SXin Li
62*9c5db199SXin Li    """
63*9c5db199SXin Li    if not is_prod_ci:
64*9c5db199SXin Li        is_smds_test = random.choice([True, False])
65*9c5db199SXin Li        logging.info('is_smds_test %s', is_smds_test)
66*9c5db199SXin Li        if is_smds_test:
67*9c5db199SXin Li            installed_iccid = install_pending_profile_test(
68*9c5db199SXin Li            euicc_path, hermes_manager)
69*9c5db199SXin Li        else:
70*9c5db199SXin Li            installed_iccid = install_profile_test(
71*9c5db199SXin Li            euicc_path, hermes_manager)
72*9c5db199SXin Li    else:
73*9c5db199SXin Li        installed_iccid = get_profile(
74*9c5db199SXin Li            euicc_path, hermes_manager, False)
75*9c5db199SXin Li    return installed_iccid
76*9c5db199SXin Li
77*9c5db199SXin Lidef uninstall_all_profiles(euicc_path, hermes_manager):
78*9c5db199SXin Li    """
79*9c5db199SXin Li    Uninstalls all installed test profiles
80*9c5db199SXin Li
81*9c5db199SXin Li    @param euicc_path: esim path based on testci/prodci
82*9c5db199SXin Li    @param hermes_manager: hermes manager object
83*9c5db199SXin Li    @raise error.TestFail if any dbus exception happens
84*9c5db199SXin Li
85*9c5db199SXin Li    """
86*9c5db199SXin Li    try:
87*9c5db199SXin Li        euicc, installed_profiles = \
88*9c5db199SXin Li            request_installed_profiles(euicc_path, hermes_manager)
89*9c5db199SXin Li
90*9c5db199SXin Li        profiles_count = len(installed_profiles)
91*9c5db199SXin Li        if profiles_count is 0: return
92*9c5db199SXin Li
93*9c5db199SXin Li        # also skips iccid 89010000001234567882 - R&S as its TESTING profile
94*9c5db199SXin Li        for profile in installed_profiles.keys():
95*9c5db199SXin Li            if ((hermes_constants.ProfileStateToString(
96*9c5db199SXin Li                installed_profiles[profile].state) == 'INACTIVE') and
97*9c5db199SXin Li                (hermes_constants.ProfileClassToString(
98*9c5db199SXin Li                installed_profiles[profile].profileclass) !=
99*9c5db199SXin Li                    'TESTING')):
100*9c5db199SXin Li
101*9c5db199SXin Li                logging.info('Uninstalling profile - iccid:%s',
102*9c5db199SXin Li                            installed_profiles[profile].iccid)
103*9c5db199SXin Li                euicc.uninstall_profile(profile)
104*9c5db199SXin Li        logging.info('Uninstall done')
105*9c5db199SXin Li    except dbus.DBusException as e:
106*9c5db199SXin Li        logging.error('Failed to uninstall a profile error:%s', e)
107*9c5db199SXin Li        raise error.TestFail('Failed to uninstall profile')
108*9c5db199SXin Li
109*9c5db199SXin Li
110*9c5db199SXin Lidef initialize_test(is_prod_ci_test):
111*9c5db199SXin Li    """
112*9c5db199SXin Li    Initialize euicc paths, connect to hermes, set test mode
113*9c5db199SXin Li
114*9c5db199SXin Li    @param is_prod_ci_test:  true if it is prodci test and false for testci
115*9c5db199SXin Li
116*9c5db199SXin Li    """
117*9c5db199SXin Li    logging.info('===initialize_test started===')
118*9c5db199SXin Li    mm_proxy = mm1_proxy.ModemManager1Proxy.get_proxy()
119*9c5db199SXin Li
120*9c5db199SXin Li    logging.info('Connect to Hermes')
121*9c5db199SXin Li    hermes_manager = connect_to_hermes()
122*9c5db199SXin Li
123*9c5db199SXin Li    # Always euicc/0 is prod one and euicc/1 is for test esim profiles
124*9c5db199SXin Li    # we prefer to hardcode euicc/0, since it acts as a check that Hermes
125*9c5db199SXin Li    # is able to initialize without any error. If hermes encounters an
126*9c5db199SXin Li    # error, hermes will start exposing objects such as
127*9c5db199SXin Li    # self.prod_euicc_path = "/org/chromium/Hermes/euicc/22"
128*9c5db199SXin Li    # self.test_euicc_path = "/org/chromium/Hermes/euicc/23"
129*9c5db199SXin Li
130*9c5db199SXin Li    euicc = None
131*9c5db199SXin Li    euicc_path = None
132*9c5db199SXin Li    for path in hermes_manager.get_available_euiccs():
133*9c5db199SXin Li        logging.info("Found euicc at %s", path)
134*9c5db199SXin Li        is_prod_euicc = not hermes_manager.get_euicc(path).is_test_euicc()
135*9c5db199SXin Li        if is_prod_euicc == is_prod_ci_test:
136*9c5db199SXin Li            euicc_path = path
137*9c5db199SXin Li            euicc = hermes_manager.get_euicc(euicc_path)
138*9c5db199SXin Li            break
139*9c5db199SXin Li
140*9c5db199SXin Li    if not euicc:
141*9c5db199SXin Li        raise error.TestFail("Initialize test failed, " +
142*9c5db199SXin Li                             "prod" if is_prod_ci_test else "test" +
143*9c5db199SXin Li                             " euicc not found")
144*9c5db199SXin Li
145*9c5db199SXin Li    euicc.use_test_certs(not is_prod_ci_test)
146*9c5db199SXin Li
147*9c5db199SXin Li    if not is_prod_ci_test:
148*9c5db199SXin Li        uninstall_all_profiles(euicc_path, hermes_manager)
149*9c5db199SXin Li    logging.info('===initialize_test done===\n')
150*9c5db199SXin Li    return  mm_proxy, hermes_manager, euicc_path
151*9c5db199SXin Li
152*9c5db199SXin Lidef validate_profile_state(euicc_path, hermes_manager, iccid, is_enable):
153*9c5db199SXin Li    """
154*9c5db199SXin Li    Validates given profile(iccid) state
155*9c5db199SXin Li
156*9c5db199SXin Li    Check state of changed profile
157*9c5db199SXin Li
158*9c5db199SXin Li    @param euicc_path: esim path based on testci/prodci
159*9c5db199SXin Li    @param hermes_manager: hermes manager object
160*9c5db199SXin Li    @param iccid: iccid of the profile enabled/disabled
161*9c5db199SXin Li    @param is_enable: true to enable profile and false to disable
162*9c5db199SXin Li    @raise error.TestFail if any dbus exception happens
163*9c5db199SXin Li
164*9c5db199SXin Li    """
165*9c5db199SXin Li    try:
166*9c5db199SXin Li        target_state = 'ACTIVE' if is_enable else 'INACTIVE'
167*9c5db199SXin Li        _, installed_profiles = \
168*9c5db199SXin Li        request_installed_profiles(euicc_path, hermes_manager)
169*9c5db199SXin Li
170*9c5db199SXin Li        # check profile with given iccid has target_state and rest are opposite
171*9c5db199SXin Li        for profile in installed_profiles.values():
172*9c5db199SXin Li            # check for inactive profiles when enabled except enabled one
173*9c5db199SXin Li            if iccid == profile.iccid:
174*9c5db199SXin Li                if not (hermes_constants.ProfileStateToString(profile.state) ==
175*9c5db199SXin Li                    target_state):
176*9c5db199SXin Li                    logging.error('profile:%s not in %s state',
177*9c5db199SXin Li                    profile.iccid, target_state)
178*9c5db199SXin Li                    raise error.TestFail('validate_profile_state failed')
179*9c5db199SXin Li
180*9c5db199SXin Li        logging.info('validate_profile_state succeeded')
181*9c5db199SXin Li    except dbus.DBusException as e:
182*9c5db199SXin Li        logging.error('Profile %s error:%s', target_state, e)
183*9c5db199SXin Li        raise error.TestFail('validate_profile_state failed')
184*9c5db199SXin Li
185*9c5db199SXin Lidef set_profile_state(
186*9c5db199SXin Li    is_active, euicc_path=None, hermes_manager=None,  iccid=None, profile=None):
187*9c5db199SXin Li    """
188*9c5db199SXin Li    Enable or Disable already enabled/disabled profile
189*9c5db199SXin Li
190*9c5db199SXin Li    @param is_active: True to enable, False to disable profile
191*9c5db199SXin Li    @param euicc_path: esim path based on testci/prodci
192*9c5db199SXin Li    @param hermes_manager: hermes manager object
193*9c5db199SXin Li    @param iccid: profile iccid to enable
194*9c5db199SXin Li    @param profile: profile object to enable/disable
195*9c5db199SXin Li    @raise error.TestFail if expected error not resulted
196*9c5db199SXin Li
197*9c5db199SXin Li    """
198*9c5db199SXin Li    logging.info('set_profile_state start')
199*9c5db199SXin Li    if euicc_path and iccid:
200*9c5db199SXin Li        euicc = hermes_manager.get_euicc(euicc_path)
201*9c5db199SXin Li        profile = euicc.get_profile_from_iccid(iccid)
202*9c5db199SXin Li
203*9c5db199SXin Li    if is_active:
204*9c5db199SXin Li        profile.enable()
205*9c5db199SXin Li    else:
206*9c5db199SXin Li        profile.disable()
207*9c5db199SXin Li    logging.info('set_profile_state done')
208*9c5db199SXin Li
209*9c5db199SXin Lidef get_profile_state(euicc_path, hermes_manager, iccid):
210*9c5db199SXin Li    """
211*9c5db199SXin Li    get profile state
212*9c5db199SXin Li
213*9c5db199SXin Li    @param euicc_path: esim path based on testci/prodci
214*9c5db199SXin Li    @param hermes_manager: hermes manager object
215*9c5db199SXin Li    @param iccid: profile iccid to find state
216*9c5db199SXin Li    @return True if profile state is Active and False if state is Inactive
217*9c5db199SXin Li
218*9c5db199SXin Li    """
219*9c5db199SXin Li    if euicc_path and iccid:
220*9c5db199SXin Li        euicc = hermes_manager.get_euicc(euicc_path)
221*9c5db199SXin Li        profile = euicc.get_profile_from_iccid(iccid)
222*9c5db199SXin Li
223*9c5db199SXin Li    return True if (hermes_constants.ProfileStateToString(profile.state) ==
224*9c5db199SXin Li                    'ACTIVE') else False
225*9c5db199SXin Li
226*9c5db199SXin Lidef get_profile(euicc_path, hermes_manager, is_active):
227*9c5db199SXin Li    """
228*9c5db199SXin Li    Returns a active/inactive profile on given euicc
229*9c5db199SXin Li
230*9c5db199SXin Li    This is to get already enabled or disabled profile. if not found enabled
231*9c5db199SXin Li    profile, enable an inactive profile and if not found disable profile
232*9c5db199SXin Li    disable an active profile
233*9c5db199SXin Li
234*9c5db199SXin Li    @param euicc_path: esim path based on testci/prodci
235*9c5db199SXin Li    @param hermes_manager: hermes manager object
236*9c5db199SXin Li    @param is_active: True to get active profile, False to get inactive profile
237*9c5db199SXin Li    @return iccid: iccid of the active/inactive profile as requested
238*9c5db199SXin Li    @raise error.TestFail if any dbus exception happens
239*9c5db199SXin Li
240*9c5db199SXin Li    """
241*9c5db199SXin Li    try:
242*9c5db199SXin Li        _, installed_profiles = \
243*9c5db199SXin Li            request_installed_profiles(euicc_path, hermes_manager)
244*9c5db199SXin Li
245*9c5db199SXin Li        profile_found = False
246*9c5db199SXin Li        iccid = None
247*9c5db199SXin Li        profile_needed = 'Enabled' if is_active else 'Disabled'
248*9c5db199SXin Li        # Find active/inactive profile
249*9c5db199SXin Li        target_state = 'ACTIVE' if is_active else 'INACTIVE'
250*9c5db199SXin Li
251*9c5db199SXin Li        for profile in installed_profiles.values():
252*9c5db199SXin Li            # skipping TESTING profiles to prevent install/uninstall operations
253*9c5db199SXin Li            if (hermes_constants.ProfileClassToString(
254*9c5db199SXin Li                                profile.profileclass) == 'TESTING'):
255*9c5db199SXin Li                continue
256*9c5db199SXin Li
257*9c5db199SXin Li            if not (hermes_constants.ProfileStateToString(profile.state) ==
258*9c5db199SXin Li                                target_state):
259*9c5db199SXin Li                set_profile_state(is_active, profile=profile)
260*9c5db199SXin Li
261*9c5db199SXin Li            profile_found = True
262*9c5db199SXin Li            return profile.iccid
263*9c5db199SXin Li
264*9c5db199SXin Li        if not profile_found:
265*9c5db199SXin Li            logging.error('No installed profile which is %s', profile_needed)
266*9c5db199SXin Li        return iccid
267*9c5db199SXin Li    except dbus.DBusException as e:
268*9c5db199SXin Li        raise error.TestFail('get_profile failed :', repr(e))
269*9c5db199SXin Li
270*9c5db199SXin Lidef get_iccid_of_disabled_profile(euicc_path, hermes_manager, is_prod_ci):
271*9c5db199SXin Li    """
272*9c5db199SXin Li    Get profile with disabled status and return its iccid
273*9c5db199SXin Li
274*9c5db199SXin Li    For test esim install new profile and return iccid of that profile
275*9c5db199SXin Li    For prod esim having two profiles is prerequisite, return disabled profile
276*9c5db199SXin Li
277*9c5db199SXin Li    @param euicc_path: esim path based on testci/prodci
278*9c5db199SXin Li    @param hermes_manager: hermes manager object
279*9c5db199SXin Li    @param is_prod_ci:  true if it is prodci test and false for testci
280*9c5db199SXin Li    @return iccid: iccid of the installed profile or None
281*9c5db199SXin Li
282*9c5db199SXin Li    """
283*9c5db199SXin Li    if not is_prod_ci:
284*9c5db199SXin Li        installed_iccid = install_profile_test(euicc_path, hermes_manager)
285*9c5db199SXin Li    else:
286*9c5db199SXin Li        # get disabled profile on a prod esim, if not exist then do disable one
287*9c5db199SXin Li        _, installed_profiles = \
288*9c5db199SXin Li        request_installed_profiles(euicc_path, hermes_manager)
289*9c5db199SXin Li        for profile in installed_profiles.values():
290*9c5db199SXin Li            if (hermes_constants.ProfileClassToString(profile.profileclass) ==
291*9c5db199SXin Li                    'TESTING'):
292*9c5db199SXin Li                continue
293*9c5db199SXin Li
294*9c5db199SXin Li            if (hermes_constants.ProfileStateToString(profile.state) ==
295*9c5db199SXin Li                    'INACTIVE'):
296*9c5db199SXin Li                return profile.iccid
297*9c5db199SXin Li
298*9c5db199SXin Li        installed_iccid = get_profile(euicc_path, hermes_manager, False)
299*9c5db199SXin Li
300*9c5db199SXin Li    return installed_iccid
301*9c5db199SXin Li
302*9c5db199SXin Li# Test functions
303*9c5db199SXin Lidef enable_or_disable_profile_test(
304*9c5db199SXin Li    euicc_path, hermes_manager, iccid, is_enable):
305*9c5db199SXin Li    """
306*9c5db199SXin Li    Validates enable/disable profile api DBus call
307*9c5db199SXin Li
308*9c5db199SXin Li    @param euicc_path: esim path based on testci/prodci
309*9c5db199SXin Li    @param hermes_manager: hermes manager object
310*9c5db199SXin Li    @param iccid: iccid of the profile to be enabled/disabled
311*9c5db199SXin Li    @param is_enable: true to enable profile and false to disable
312*9c5db199SXin Li    @raise error.TestFail if any dbus exception happens
313*9c5db199SXin Li
314*9c5db199SXin Li    """
315*9c5db199SXin Li    try:
316*9c5db199SXin Li        logging.info('===enable_or_disable_profile_test started===')
317*9c5db199SXin Li        profile_action = 'Enable' if is_enable else 'Disable'
318*9c5db199SXin Li        logging.info('%s :', profile_action)
319*9c5db199SXin Li        euicc, installed_profiles = \
320*9c5db199SXin Li            request_installed_profiles(euicc_path, hermes_manager)
321*9c5db199SXin Li        # Profile objects maybe stale if IsActive is false
322*9c5db199SXin Li        # Switch to the euicc we are interested in before
323*9c5db199SXin Li        # performing an op.
324*9c5db199SXin Li
325*9c5db199SXin Li        profile_found = False
326*9c5db199SXin Li        target_state = 'ACTIVE' if is_enable else 'INACTIVE'
327*9c5db199SXin Li        # Find active or inactive profile to enable/disable
328*9c5db199SXin Li        for profile in installed_profiles.values():
329*9c5db199SXin Li            if not (hermes_constants.ProfileStateToString(profile.state) ==
330*9c5db199SXin Li                    target_state):
331*9c5db199SXin Li                if iccid is None or iccid == profile.iccid:
332*9c5db199SXin Li                    logging.info('Profile to %s:%s', profile_action,
333*9c5db199SXin Li                                profile.iccid)
334*9c5db199SXin Li                    profile_found = True
335*9c5db199SXin Li                    set_profile_state(is_enable, profile=profile)
336*9c5db199SXin Li                    logging.info('===enable_or_disable_profile_test '
337*9c5db199SXin Li                                'succeeded===\n')
338*9c5db199SXin Li                    break
339*9c5db199SXin Li        if not profile_found:
340*9c5db199SXin Li            raise error.TestFail('enable_or_disable_profile_test failed -'
341*9c5db199SXin Li                    'No profile to ' + profile_action)
342*9c5db199SXin Li        # Check profile state
343*9c5db199SXin Li        validate_profile_state(euicc_path, hermes_manager, iccid, is_enable)
344*9c5db199SXin Li    except dbus.DBusException as e:
345*9c5db199SXin Li        logging.error('Profile %s error:%s', profile_action, e)
346*9c5db199SXin Li        raise error.TestFail('enable_or_disable_profile_test Failed')
347*9c5db199SXin Li
348*9c5db199SXin Lidef install_profile_test(euicc_path, hermes_manager):
349*9c5db199SXin Li    """
350*9c5db199SXin Li    Validates InstallProfileFromActivationCode api on test euicc
351*9c5db199SXin Li
352*9c5db199SXin Li    use SMDS calls to find iccid, activation code from pending profiles
353*9c5db199SXin Li    and install those profiles, this requires profiles generated based
354*9c5db199SXin Li    on EID of test esims in lab devices
355*9c5db199SXin Li
356*9c5db199SXin Li    @param euicc_path: esim path based on testci/prodci
357*9c5db199SXin Li    @param hermes_manager: hermes manager object
358*9c5db199SXin Li    @return iccid: iccid of the installed profile or None
359*9c5db199SXin Li    @raise error.TestFail if any dbus exception happens
360*9c5db199SXin Li
361*9c5db199SXin Li    """
362*9c5db199SXin Li    try:
363*9c5db199SXin Li        # get all pending profiles which are generated on DUT EID
364*9c5db199SXin Li        # Read all profiles activation code from pending profile dict
365*9c5db199SXin Li        # Install a profile from activation code, have iccid and
366*9c5db199SXin Li        # Check the presence of this profile after installation
367*9c5db199SXin Li
368*9c5db199SXin Li        logging.info('===install_profile_test started===')
369*9c5db199SXin Li        activation_code = None
370*9c5db199SXin Li        confirmation_code = ""
371*9c5db199SXin Li        iccid = None
372*9c5db199SXin Li        euicc = None
373*9c5db199SXin Li
374*9c5db199SXin Li        euicc, installed_profiles = \
375*9c5db199SXin Li            request_installed_profiles(euicc_path, hermes_manager)
376*9c5db199SXin Li
377*9c5db199SXin Li        euicc.request_pending_profiles(dbus.String('prod.smds.rsp.goog'))
378*9c5db199SXin Li        logging.info('euicc chosen:%s', euicc_path)
379*9c5db199SXin Li        profiles_pending = euicc.get_pending_profiles()
380*9c5db199SXin Li        if not profiles_pending:
381*9c5db199SXin Li            logging.error('install_profile_test: pending profile not found')
382*9c5db199SXin Li            raise error.TestFail('No pending profile found on euicc:',
383*9c5db199SXin Li                                 euicc_path)
384*9c5db199SXin Li
385*9c5db199SXin Li        profile_path_to_install, profile_to_install = \
386*9c5db199SXin Li            list(profiles_pending.items())[0]
387*9c5db199SXin Li        logging.debug('First pending profile:%s', profile_path_to_install)
388*9c5db199SXin Li
389*9c5db199SXin Li        iccid = profile_to_install.iccid
390*9c5db199SXin Li        activation_code = profile_to_install.activationcode
391*9c5db199SXin Li
392*9c5db199SXin Li        logging.info('Installing iccid:%s act_code:%s conf_code:%s',
393*9c5db199SXin Li                     iccid, activation_code, confirmation_code)
394*9c5db199SXin Li        # Install
395*9c5db199SXin Li        euicc.install_profile_from_activation_code(
396*9c5db199SXin Li            activation_code, confirmation_code)
397*9c5db199SXin Li
398*9c5db199SXin Li        # Check if iccid found in installed profiles, installation success
399*9c5db199SXin Li        installed_profiles = euicc.get_installed_profiles()
400*9c5db199SXin Li
401*9c5db199SXin Li        if ((installed_profiles[profile_path_to_install] is None) or
402*9c5db199SXin Li            (installed_profiles[profile_path_to_install].iccid !=
403*9c5db199SXin Li             profile_to_install.iccid)):
404*9c5db199SXin Li            logging.error('install_profile_test failed. Test Failed.')
405*9c5db199SXin Li            raise error.TestFail('No installed profile found on euicc:',
406*9c5db199SXin Li                                 euicc_path)
407*9c5db199SXin Li
408*9c5db199SXin Li        logging.info('===install_profile_test succeeded===\n')
409*9c5db199SXin Li        return iccid
410*9c5db199SXin Li    except dbus.DBusException as e:
411*9c5db199SXin Li        logging.error('Failed to install a pending profile')
412*9c5db199SXin Li        raise error.TestFail('install_profile_test failed with ',
413*9c5db199SXin Li                             repr(e))
414*9c5db199SXin Li
415*9c5db199SXin Lidef install_pending_profile_test(euicc_path, hermes_manager):
416*9c5db199SXin Li    """
417*9c5db199SXin Li    Validates InstallPendingProfile api on test euicc
418*9c5db199SXin Li    Find a profile from list of esim pending profiles which is not
419*9c5db199SXin Li    installed yet and install that profile
420*9c5db199SXin Li
421*9c5db199SXin Li    Required to create pending profiles for each EID(euicc sim) in lab dut.
422*9c5db199SXin Li    create profiles from stork giving lab devices EID. puts profiles in
423*9c5db199SXin Li    pending state for that euicc when RequestPendingProfiles called.
424*9c5db199SXin Li
425*9c5db199SXin Li    @param euicc_path: esim path based on testci/prodci
426*9c5db199SXin Li    @param hermes_manager: hermes manager object
427*9c5db199SXin Li    @return iccid: iccid of the installed profile or None
428*9c5db199SXin Li    @raise error.TestFail if any dbus exception happens
429*9c5db199SXin Li
430*9c5db199SXin Li    """
431*9c5db199SXin Li    logging.info('===install_pending_profile_test started===')
432*9c5db199SXin Li    profile_to_install = None
433*9c5db199SXin Li
434*9c5db199SXin Li    euicc, installed_profiles = \
435*9c5db199SXin Li            request_installed_profiles(euicc_path, hermes_manager)
436*9c5db199SXin Li
437*9c5db199SXin Li    euicc.request_pending_profiles(dbus.String('prod.smds.rsp.goog'))
438*9c5db199SXin Li    profiles_pending = euicc.get_pending_profiles()
439*9c5db199SXin Li    if not profiles_pending:
440*9c5db199SXin Li        logging.error(
441*9c5db199SXin Li            'install_pending_profile_test: pending profile not found')
442*9c5db199SXin Li        raise error.TestFail('No pending profile found on euicc:',
443*9c5db199SXin Li                             euicc_path)
444*9c5db199SXin Li
445*9c5db199SXin Li    profile_path_to_install, profile_to_install = list(profiles_pending.items())[0]
446*9c5db199SXin Li    iccid = profile_to_install.iccid
447*9c5db199SXin Li    activation_code = profile_to_install.activationcode
448*9c5db199SXin Li
449*9c5db199SXin Li    logging.info('Installing profile:%s iccid:%s act_code:%s',
450*9c5db199SXin Li                 profile_path_to_install, iccid, activation_code)
451*9c5db199SXin Li
452*9c5db199SXin Li    try:
453*9c5db199SXin Li        # Install
454*9c5db199SXin Li        profile = euicc.install_pending_profile(
455*9c5db199SXin Li            profile_path_to_install, "")
456*9c5db199SXin Li        logging.info('Installed pending profile is %s', profile)
457*9c5db199SXin Li        if not profile:
458*9c5db199SXin Li            logging.error('No profile object returned after install')
459*9c5db199SXin Li            return None
460*9c5db199SXin Li    except dbus.DBusException as e:
461*9c5db199SXin Li        logging.error('Failed to install pending profile:%s', e)
462*9c5db199SXin Li        raise error.TestFail('Failed to install pending profile',
463*9c5db199SXin Li                                   repr(e))
464*9c5db199SXin Li
465*9c5db199SXin Li    # Find above installed profile, if not exists raise test failure
466*9c5db199SXin Li    installed_profiles = euicc.get_installed_profiles()
467*9c5db199SXin Li    if ((installed_profiles[profile_path_to_install] is None) or
468*9c5db199SXin Li        (installed_profiles[profile_path_to_install].iccid !=
469*9c5db199SXin Li         profile_to_install.iccid)):
470*9c5db199SXin Li        raise error.TestFail('Install pending profile failed :',
471*9c5db199SXin Li                             profile_path_to_install)
472*9c5db199SXin Li
473*9c5db199SXin Li    logging.info('===install_pending_profile_test succeeded===\n')
474*9c5db199SXin Li    return iccid
475*9c5db199SXin Li
476*9c5db199SXin Lidef uninstall_profile_test(euicc_path, hermes_manager, iccid):
477*9c5db199SXin Li    """
478*9c5db199SXin Li    Validates UninstallProfile api by uninstalling any randomly
479*9c5db199SXin Li    selected installed profile
480*9c5db199SXin Li
481*9c5db199SXin Li    @param euicc_path: esim path based on testci/prodci
482*9c5db199SXin Li    @param hermes_manager: hermes manager object
483*9c5db199SXin Li    @param iccid: iccid of the profile to be uninstalled
484*9c5db199SXin Li    @raise error.TestFail if any dbus exception happens
485*9c5db199SXin Li
486*9c5db199SXin Li    """
487*9c5db199SXin Li    logging.info('===uninstall_profile_test started===')
488*9c5db199SXin Li    # Getinstalled profiles list and randomly uninstall a profile
489*9c5db199SXin Li    try:
490*9c5db199SXin Li        euicc, installed_profiles = \
491*9c5db199SXin Li            request_installed_profiles(euicc_path, hermes_manager)
492*9c5db199SXin Li
493*9c5db199SXin Li        profile_to_uninstall = euicc.get_profile_from_iccid(iccid)
494*9c5db199SXin Li        if not profile_to_uninstall:
495*9c5db199SXin Li            raise error.TestFail('No valid profile found at:', euicc_path)
496*9c5db199SXin Li
497*9c5db199SXin Li        profile_path = profile_to_uninstall.path
498*9c5db199SXin Li        uninstalled_profile = None
499*9c5db199SXin Li
500*9c5db199SXin Li        # Hermes does not support uninstalling test profiles yet.
501*9c5db199SXin Li        if hermes_constants.ProfileClassToString(
502*9c5db199SXin Li                profile_to_uninstall.profileclass) != 'TESTING':
503*9c5db199SXin Li            logging.info('profile to uninstall is:%s', profile_path)
504*9c5db199SXin Li            euicc.uninstall_profile(profile_path)
505*9c5db199SXin Li            uninstalled_profile = profile_path
506*9c5db199SXin Li            logging.info('uninstall_profile_test succeeded')
507*9c5db199SXin Li
508*9c5db199SXin Li        if not uninstalled_profile:
509*9c5db199SXin Li            raise error.TestFail(
510*9c5db199SXin Li                'uninstall_profile_test failed - No uninstallable profile')
511*9c5db199SXin Li
512*9c5db199SXin Li        # Try to find the uninstalled profile, if exists raise test failure
513*9c5db199SXin Li        profiles_installed = euicc.get_installed_profiles()
514*9c5db199SXin Li        for profile in profiles_installed.keys():
515*9c5db199SXin Li            if uninstalled_profile in profile:
516*9c5db199SXin Li                raise error.TestFail('uninstall_profile_test profile Failed')
517*9c5db199SXin Li        logging.info('===uninstall_profile_test succeeded===\n')
518*9c5db199SXin Li    except dbus.DBusException as e:
519*9c5db199SXin Li        raise error.TestFail('Failed to uninstall profile', e)
520