1# Copyright (c) 2013 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
5from autotest_lib.client.bin import utils
6from autotest_lib.client.common_lib import error
7
8"""
9This module contains functions that are commonly used by tests while
10interacting with a ChromeNetworkingTestContext.
11
12"""
13
14LONG_TIMEOUT = 120
15SHORT_TIMEOUT = 10
16
17def get_ui_property(network, property_name, expansion_level=1):
18    """
19    Returns the value of the property by applying a '.'-delimited path
20    expansion, or None if the property is not found.
21
22    @param network: A JSON dictionary containing network data, as returned by
23            chrome.networkingPrivate.
24    @param property_name: The property to obtain.
25    @param expansion_level: Denotes the number of levels to descend through
26            property based on the path expansion. For example, for property
27            "A.B.C":
28
29                level: 0
30                return: props["A.B.C"]
31
32                level: 1
33                return: props["A"]["B.C"]
34
35                level: >2
36                return: props["A"]["B"]["C"]
37
38    @return The value of the requested property, or None if not found.
39
40    """
41    path = property_name.split('.', expansion_level)
42    result = network
43    for key in path:
44        value = result.get(key, None)
45        if value is None:
46            return None
47        result = value
48    return result
49
50
51def check_ui_property(chrome_networking_test_context,
52                      network_guid,
53                      property_name,
54                      expected_value,
55                      expansion_level=1,
56                      timeout=LONG_TIMEOUT):
57    """
58    Polls until the given network property has the expected value.
59
60    @param chrome_networking_test_context: Instance of
61            chrome_networking_test_context.ChromeNetworkingTestContext.
62    @param network_guid: GUID of the network.
63    @param property_name: Property to check.
64    @param expected_value: Value the property is expected to obtain.
65    @param expansion_level: Path expansion depth.
66    @param timeout: Timeout interval in which the property should reach the
67            expected value.
68
69    @raises error.TestFail, if the check doesn't pass within |timeout|.
70
71    """
72    def _compare_props():
73        network = call_test_function_check_success(
74                chrome_networking_test_context,
75                'getNetworkInfo',
76                ('"' + network_guid + '"',))
77        value = get_ui_property(network, property_name, expansion_level)
78        return value == expected_value
79    utils.poll_for_condition(
80            _compare_props,
81            error.TestFail('Property "' + property_name + '" on network "' +
82                           network_guid + '" never obtained value "' +
83                           expected_value + '"'),
84            timeout)
85
86
87def simple_network_sanity_check(
88        network, expected_name, expected_type, check_name_prefix=True):
89    """
90    Simple check to ensure that the network type and name match the expected
91    values.
92
93    @param network: A JSON dictionary containing network data, as returned by
94            chrome.networkingPrivate.
95    @param expected_name: The expected value of the 'Name' property.
96    @param expected_type: The expected value of the 'Type' property.
97    @param check_name_prefix: If True, the check will not fail, as long as the
98            value of the 'Name' property starts with |expected_name|. If False,
99            this function will check for an exact match.
100
101    @raises error.TestFail if any of the checks doesn't pass.
102
103    """
104    if network['Type'] != expected_type:
105        raise error.TestFail(
106                'Expected network of type "' + expected_type + '", found ' +
107                network["Type"])
108
109    network_name = network['Name']
110    name_error_message = (
111            'Network name "%s" did not match the expected: %s (Check prefix '
112            'only=%s).' % (network_name, expected_name, check_name_prefix))
113    if ((check_name_prefix and not network_name.startswith(expected_name)) or
114        (not check_name_prefix and network_name != expected_name)):
115        raise error.TestFail(name_error_message)
116
117
118def call_test_function_check_success(
119        chrome_networking_test_context, function, args, timeout=SHORT_TIMEOUT):
120    """
121    Invokes the given function and makes sure that it succeeds. If the function
122    succeeds then the result is returned, otherwise an error.TestFail is
123    raised.
124
125    @param chrome_networking_test_context: Instance of
126            chrome_networking_test_context.ChromeNetworkingTestContext.
127    @param function: String, containing the network test function to execute.
128    @param args: Tuple of arguments to pass to |function|.
129    @param timeout: Timeout in which the function should terminate.
130
131    @raises: error.TestFail, if function returns with failure.
132
133    @return: The result value of the function. If |function| doesn't have a
134            result value, the Python equivalent of the JS "null" will be
135            returned.
136
137    """
138    call_status = chrome_networking_test_context.call_test_function(
139            timeout, function, *args)
140    if call_status['status'] != chrome_networking_test_context.STATUS_SUCCESS:
141        raise error.TestFail('Function "' + function + '" did not return with '
142                             'status SUCCESS: ' + str(call_status))
143    return call_status['result']
144