Add a controller class to manage RF Switch.
This controller class gets all AP boxes and Client Boxes attached to the
RF Switch. Adding unit tests.
BUG=b:34983942
TEST=None
Change-Id: If541ef5815cf4fafd4466e28edea26218251f76a
Reviewed-on: https://chromium-review.googlesource.com/451577
Commit-Ready: Ashakiran Byrappa <abyrappa@google.com>
Tested-by: Ashakiran Byrappa <abyrappa@google.com>
Reviewed-by: Harpreet Grewal <harpreet@chromium.org>
Reviewed-by: Kris Rambish <krisr@chromium.org>
Reviewed-by: Godofredo Contreras <godofredoc@chromium.org>
diff --git a/server/cros/network/rf_switch_controller.py b/server/cros/network/rf_switch_controller.py
new file mode 100644
index 0000000..d8dca5c
--- /dev/null
+++ b/server/cros/network/rf_switch_controller.py
@@ -0,0 +1,76 @@
+# Copyright (c) 2017 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.
+
+"""RF Switch is a device used to route WiFi signals through RF cables
+between 4 isolation boxes with APs and 4 isolation boxes with DUTs.
+
+RFSwitchController Class provides methods to control RF Switch.
+
+This class can be used to:
+1) retrieve all APBoxes and ClientBoxes connected to the RF Switch.
+2) connect Client and AP Boxes for testing.
+3) retrieve information about current connections.
+4) reset all connections.
+"""
+
+import logging
+
+from autotest_lib.server import frontend
+from autotest_lib.server import site_utils
+from autotest_lib.server.cros.network import rf_switch_ap_box
+from autotest_lib.server.cros.network import rf_switch_client_box
+
+
+RF_SWITCH_STR = 'rf_switch_'
+RF_SWITCH_CLIENT = 'rf_switch_client'
+RF_SWITCH_APS = 'rf_switch_aps'
+
+
+class RFSwitchController(object):
+ """Controller class to manage the RFSwitch."""
+
+
+ def __init__(self, rf_switch_host):
+ """Constructor for RF Switch Controller.
+
+ @param rf_switch_host: An AFE Host object of RF Switch.
+ """
+ self.rf_switch_host = rf_switch_host
+ self.rf_switch_labels = rf_switch_host.labels
+ # RF Switches are named as rf_switch_1, rf_switch_2 using labels.
+ # To find the rf_switch, find label starting with 'rf_switch_'
+ labels = [
+ s for s in self.rf_switch_labels if s.startswith(RF_SWITCH_STR)]
+ afe = frontend.AFE(
+ debug=True, server=site_utils.get_global_afe_hostname())
+ self.hosts = afe.get_hosts(label=labels)
+ self.ap_boxes = []
+ self.client_boxes = []
+ for host in self.hosts:
+ if RF_SWITCH_APS in host.labels:
+ self.ap_boxes.append(rf_switch_ap_box.APBox(host))
+ elif RF_SWITCH_CLIENT in host.labels:
+ self.client_boxes.append(rf_switch_client_box.ClientBox(host))
+ if not self.ap_boxes:
+ logging.error('No AP boxes available for the RF Switch.')
+ if not self.client_boxes:
+ logging.error('No Client boxes available for the RF Switch.')
+
+
+ def get_ap_boxes(self):
+ """Returns all AP Boxes connected to the RF Switch.
+
+ @returns a list of
+ autotest_lib.server.cros.network.rf_switch_ap_box.APBox objects.
+ """
+ return self.ap_boxes
+
+
+ def get_client_boxes(self):
+ """Returns all Client Boxes connected to the RF Switch.
+
+ @returns a list of
+ autotest_lib.server.cros.network.rf_switch_client_box.ClientBox objects.
+ """
+ return self.client_boxes
diff --git a/server/cros/network/rf_switch_controller_test.py b/server/cros/network/rf_switch_controller_test.py
new file mode 100644
index 0000000..9b24463
--- /dev/null
+++ b/server/cros/network/rf_switch_controller_test.py
@@ -0,0 +1,100 @@
+"""Tests for rf_switch_controller class."""
+
+import unittest
+
+import mock
+
+from autotest_lib.server import frontend
+from autotest_lib.server import site_utils
+from autotest_lib.server.cros.network import rf_switch_controller
+
+
+class RfSwitchControllerTest(unittest.TestCase):
+ """Tests for RF Switch Controller class."""
+
+
+ RF_SWITCH_CLIENT = 'rf_switch_client'
+ RF_SWITCH_APS = 'rf_switch_aps'
+
+
+ def setUp(self):
+ """Initial setup required to test the methods.
+
+ Create three hosts: RF Switch, AP Box and Client Box. Assign the
+ hostnames and labels. Create an instance of RfSwitchController and
+ add mock hosts.
+ """
+ self.rf_switch_host = frontend.Host('', '')
+ self.ap_box_host = frontend.Host('', '')
+ self.client_box_host = frontend.Host('', '')
+
+ self.rf_switch_host.hostname = 'chromeos9-rfswitch'
+ self.ap_box_host.hostname = 'chromeos9-apbox1'
+ self.client_box_host.hostname = 'chromeos9-clientbox1'
+
+ self.rf_switch_host.labels = ['rf_switch', 'rf_switch_1']
+ self.ap_box_host.labels = ['rf_switch_1', 'ap_box_1', 'rf_switch_aps']
+ self.client_box_host.labels = [
+ 'rf_switch_1', 'client_box_1', 'rf_switch_client']
+
+
+ @mock.patch('autotest_lib.server.frontend.AFE')
+ def testGetAPBoxes(self, mock_afe):
+ """Test to get all AP Boxes connected to the RF Switch."""
+ afe_instance = mock_afe()
+ afe_instance.get_hosts.return_value = [
+ self.ap_box_host, self.client_box_host]
+ rf_switch_manager = rf_switch_controller.RFSwitchController(
+ self.rf_switch_host)
+ ap_boxes = rf_switch_manager.get_ap_boxes()
+ self.assertEquals(len(ap_boxes), 1)
+ ap_box = ap_boxes[0]
+ self.assertEquals(ap_box.ap_box_host.hostname, 'chromeos9-apbox1')
+
+
+ @mock.patch('autotest_lib.server.frontend.AFE')
+ def testGetClientBoxes(self, mock_afe):
+ """Test to get all Client Boxes connected to the RF Switch."""
+ afe_instance = mock_afe()
+ afe_instance.get_hosts.return_value = [
+ self.ap_box_host, self.client_box_host]
+ rf_switch_manager = rf_switch_controller.RFSwitchController(
+ self.rf_switch_host)
+ client_boxes = rf_switch_manager.get_client_boxes()
+ self.assertEquals(len(client_boxes), 1)
+ client_box = client_boxes[0]
+ self.assertEquals(
+ client_box.client_box_host.hostname, 'chromeos9-clientbox1')
+
+
+ @mock.patch('autotest_lib.server.frontend.AFE')
+ def testRfSwitchNotConnectedToAPBoxes(self, mock_afe):
+ """Testing scenario when RF Switch is not connnected to AP Boxes."""
+ afe_instance = mock_afe()
+ afe_instance.get_hosts.return_value = [self.client_box_host]
+ with mock.patch('logging.Logger.error') as mock_logger:
+ rf_switch_manager = rf_switch_controller.RFSwitchController(
+ self.rf_switch_host)
+ mock_logger.assert_called_with(
+ 'No AP boxes available for the RF Switch.')
+ ap_boxes = rf_switch_manager.get_ap_boxes()
+ self.assertEquals(len(ap_boxes), 0)
+
+
+ @mock.patch('autotest_lib.server.frontend.AFE')
+ def testClientBoxWithInvalidLabels(self, mock_afe):
+ """Test when RF Switch connected to Client Box with invalid labels."""
+ afe_instance = mock_afe()
+ self.client_box_host.labels = ['rf_switch_1', 'client_1', 'rf_client']
+ afe_instance.get_hosts.return_value = [self.client_box_host]
+ with mock.patch('logging.Logger.error') as mock_logger:
+ rf_switch_manager = rf_switch_controller.RFSwitchController(
+ self.rf_switch_host)
+ mock_logger.assert_called_with(
+ 'No Client boxes available for the RF Switch.')
+ client_boxes = rf_switch_manager.get_client_boxes()
+ self.assertEquals(len(client_boxes), 0)
+
+
+if __name__ == '__main__':
+ unittest.main()