blob: ebdb1f29abb34ab827cbb89359e431225fba9a95 [file] [log] [blame] [edit]
# Copyright 2019 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import pickle
import re
from autotest_lib.client.common_lib import error
from autotest_lib.client.cros.enterprise import enterprise_policy_base
from autotest_lib.client.cros.enterprise import enterprise_network_api
class policy_GlobalNetworkSettings(
enterprise_policy_base.EnterprisePolicyTest):
version = 1
def cleanup(self):
"""Re-enable ethernet after the test is completed."""
if hasattr(self, 'net_api'):
self.net_api.chrome_net_context.enable_network_device('Ethernet')
super(policy_GlobalNetworkSettings, self).cleanup()
def _test_only_connect_if_available(self, policy_error, user_error):
"""
Verify the AllowOnlyPolicyNetworksToConnectIfAvailable policy.
If both networks are available, only the policy network should
connect. If the policy network is unavailable, then the user network
may connect. Ensure the errors are caused by the policy blocking or
allowing the correct connections.
@param policy_error: Error (if any) raised from connecting to policy
network.
@param user_error: Error (if any) raised from connecting to user
network.
@raises error.TestFail: If errors do not match policy behavior.
"""
OUT_OF_RANGE_ERROR = 'The SSID: .* is not in WiFi range of the DUT'
BLOCKED_ERROR = ('Could not connect to .* network. '
'Error returned by chrome.networkingPrivate.'
'startConnect API: blocked-by-policy')
if policy_error and user_error:
raise error.TestFail(
'Unable to connect to user or policy network: %s'
% policy_error)
elif not policy_error and user_error:
if not re.match(BLOCKED_ERROR, str(user_error)):
raise error.TestFail('Network API received unrecognized '
'error connecting to the user '
'network: %s' % user_error)
elif policy_error and not user_error:
if not re.match(OUT_OF_RANGE_ERROR, str(policy_error)):
raise error.TestFail('Network API received unrecognized '
'error connecting to the policy '
'network: %s' % policy_error)
elif not (policy_error or user_error):
raise error.TestFail('User network connected despite policy '
'network being available')
def _test_wifi_disabled_policy(self, policy_error, user_error):
"""
Verify the DisableNetworkTypes policy on WiFi.
Both networks should show the 'No wifi networks found' error.
@param policy_error: Error (if any) raised from connecting to policy
network.
@param user_error: Error (if any) raised from connecting to user
network.
@raises error.TestFail: If errors do not match policy behavior.
"""
for err in [policy_error, user_error]:
if err is None:
raise error.TestFail('DUT was able to connect to WiFi, but '
'WiFi should be blocked.')
elif str(err) != 'No wifi networks found.':
raise error.TestFail('Network API received unrecognized '
'error connecting to network: %s'
% err)
def _test_autoconnect_policy(self, ssid, policy_network, user_network):
"""
Verify the AllowOnlyPolicyNetworksToAutoconnect policy.
Disconnect from the network. The policy network should reconnect,
and the user network should not.
@param ssid: SSID of connected network.
@param policy_network: Network policy defined network.
@param user_network: User defined network.
@raises error.TestFail: If errors do not match policy behavior.
"""
self.net_api.disconnect_from_network(ssid)
if self.net_api.is_network_connected(ssid):
if ssid == user_network.ssid:
raise error.TestFail(
'User network autoconnected despite '
'AllowOnlyPolicyNetworksToAutoconnect=True')
elif ssid == policy_network.ssid:
raise error.TestFail(
'Policy network did not autoconnect, despite '
'AllowOnlyPolicyNetworksToAutoconnect=True')
def _test_allow_only_policy(self, policy_error, user_error):
"""
Verify the AllowOnlyPolicyNetworksToConnect policy.
policy_error should be None, user_error should not.
@param policy_error: Error (if any) raised from connecting to policy
network.
@param user_error: Error (if any) raised from connecting to user
network.
@raises error.TestFail: If errors do not match policy behavior.
"""
if policy_error:
raise error.TestFail('DUT should have connected to policy '
'network, but did not: %s' % policy_error)
if not user_error:
raise error.TestFail('DUT was able to connect to user '
'network, but should have been blocked.')
def test_global_settings(self, gnc_settings, policy_network, user_network):
"""
Attempt to connect to the policy network, then the user_network.
Ensure connection behavior matches GlobalNetworkConfiguration.
@param gnc_settings: GlobalNetworkConfiguration dictionary value.
@param policy_network_pickle: NetworkConfig object representing
the policy network configuration.
@param user_network_pickle: NetworkConfig object representing
user network configuration.
@raise error.TestFail: DUT behavior does not match policy settings.
"""
# Store connection errors to check later.
network_errors = {}
for ssid in [policy_network.ssid, user_network.ssid]:
network_errors[ssid] = None
try:
self.net_api.connect_to_network(ssid)
except error.TestFail as e:
network_errors[ssid] = e
continue
if gnc_settings.get('AllowOnlyPolicyNetworksToAutoconnect'):
self._test_autoconnect_policy(ssid,
policy_network,
user_network)
continue
if not self.net_api.is_network_connected(ssid):
raise error.TestFail(
'Did not connect to network (%s)' % ssid)
policy_error = network_errors[policy_network.ssid]
user_error = network_errors[user_network.ssid]
if gnc_settings.get('AllowOnlyPolicyNetworksToConnectIfAvailable'):
self._test_only_connect_if_available(policy_error, user_error)
elif 'WiFi' in gnc_settings.get('DisableNetworkTypes', {}):
self._test_wifi_disabled_policy(policy_error, user_error)
elif gnc_settings.get('AllowOnlyPolicyNetworksToConnect'):
self._test_allow_only_policy(policy_error, user_error)
def run_once(self, gnc_settings=None, policy_network_pickle=None,
user_network_pickle=None):
"""
Setup and run the test configured for the specified test case.
policy_network is in the network policy, and user_network is not.
The GlobalNetworkConfiguration settings modify how the DUT is able to
connect to both of these networks.
@param gnc_settings: GlobalNetworkConfiguration dictionary value.
@param policy_network_pickle: Pickled NetworkConfig object to set as
the policy network configuration.
@param user_network_pickle: Pickled NetworkConfig object to set as the
user network configuration.
@raises error.TestFail: If DUT's actions do not match policy settings.
"""
if policy_network_pickle is None or user_network_pickle is None:
raise error.TestError('Networks cannot be None')
policy_network = pickle.loads(policy_network_pickle)
user_network = pickle.loads(user_network_pickle)
self.setup_case(
user_policies={'OpenNetworkConfiguration': policy_network.policy()},
device_policies={'DeviceOpenNetworkConfiguration': {
'GlobalNetworkConfiguration': gnc_settings}},
extension_paths=[
enterprise_network_api.NETWORK_TEST_EXTENSION_PATH
],
enroll=True
)
self.net_api = enterprise_network_api.\
ChromeEnterpriseNetworkContext(self.cr)
# Disable ethernet so device will default to WiFi
self.net_api.disable_network_device('Ethernet')
self.test_global_settings(gnc_settings, policy_network, user_network)