Remove test_type and rf_type argument in each API.

These two arguments are for function delegation. After delegating to
the API, they are useless. Also fixed the style of the docstring.

BUG=chromium:681734
TEST=make test

Change-Id: I762b7d1b334663e602e448604f27e4ef6b62312f
Reviewed-on: https://chromium-review.googlesource.com/428479
Commit-Ready: Chih-Yu Huang <akahuang@chromium.org>
Tested-by: Chih-Yu Huang <akahuang@chromium.org>
Reviewed-by: Joel Kitching <kitching@chromium.org>
diff --git a/graphyte/data_parser.py b/graphyte/data_parser.py
index d653c33..3b6f6cf 100644
--- a/graphyte/data_parser.py
+++ b/graphyte/data_parser.py
@@ -5,6 +5,7 @@
 # found in the LICENSE file.
 
 """The module is for parsing data in the test plan.
+
 We implement a parse function to convert string to required data type, and data
 checkers for checking the data is valid.
 """
@@ -19,7 +20,7 @@
 
 
 def Parse(string, checker=None):
-  """Convert the string to the python type.
+  """Converts the string to the python type.
 
   We only support tuple, list, None, int, float, and str.
   There are some restrictions for input:
@@ -30,8 +31,10 @@
   Args:
     string: The string to be parsed.
     checker: The rule of the result. None if no rule for the result.
+
   Returns:
     The parsed result.
+
   Raise:
     ValueError: if the result does not meet the rule.
   """
@@ -77,7 +80,8 @@
 
 
 class LiteralChecker(CheckerBase):
-  """Check whether the literal data matches one of the rules.
+  """Checks whether the literal data matches one of the rules.
+
   Data should not be list or tuple.
   Each rule might be a type (ex: int, str) or a value.
 
@@ -108,7 +112,8 @@
 
 
 class TupleChecker(CheckerBase):
-  """Check whether every field of the data matches the corresponding rules.
+  """Checks whether every field of the data matches the corresponding rules.
+
   Data type should be tuple, the length of the tuple should be the same as the
   length of the rules_list.
 
@@ -136,7 +141,8 @@
 
 
 class ListChecker(CheckerBase):
-  """Check whether all items in the data matches the rules.
+  """Checks whether all items in the data matches the rules.
+
   Data type should be list or literal, the length of the data is not limited.
 
   For example:
diff --git a/graphyte/device.py b/graphyte/device.py
new file mode 100644
index 0000000..b1f8610
--- /dev/null
+++ b/graphyte/device.py
@@ -0,0 +1,37 @@
+# Copyright 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.
+
+class ControllerBase(object):
+  """The abstract RF controller class.
+
+  The class hierarchy of the RF controller is:
+    device.ControllerBase
+    - dut.ControllerBase
+      - dut.WlanControllerBase
+      - dut.BluetoothControllerBase
+      - dut.ZigbeeControllerBase
+    - inst.ControllerBase
+      - inst.WlanControllerBase
+      - inst.BluetoothControllerBase
+      - inst.ZigbeeControllerBase
+  """
+
+  # The RF type of the controller. Child class should override this.
+  RF_TYPE = ''
+
+  def _CheckTestArgument(self, test_case, required_test_type):
+    """Checks the test case has correct test type and RF type.
+
+    Args:
+      test_case: a dict containing the test arguments.
+      required_test_type: the required test type. 'TX' or 'RX'.
+
+    Returns:
+      the test case without test type and RF type arguments.
+    """
+    assert test_case['test_type'] == required_test_type
+    assert test_case['rf_type'] == self.RF_TYPE
+    del test_case['test_type']
+    del test_case['rf_type']
+    return test_case
diff --git a/graphyte/dut/__init__.py b/graphyte/dut/__init__.py
index 46e12c7..62e5ac5 100644
--- a/graphyte/dut/__init__.py
+++ b/graphyte/dut/__init__.py
@@ -5,17 +5,21 @@
 # found in the LICENSE file.
 
 """The DUT base class.
+
 This is the virtual DUT class which every DUT plugin should implement.
 """
 
 from .. import link
 from ..default_setting import logger
+from .. import device
 
 class DUTBase(object):
   """The abstract DUT class that every DUT plugin should inherit it.
+
   It contains several RF controllers, and each controller corresponds one RF
   chip. We can control different RF chip by assigning the rf_type, and delegate
-  to the assigned controller."""
+  to the assigned controller.
+  """
 
   name = 'Virtual DUT Plugin'
   need_link = False
@@ -39,7 +43,7 @@
     self.link = link.Create(kwargs['link_options']) if self.need_link else None
 
   def __getattr__(self, name):
-    """Delegate to the active controller, that is recorded at rf_type."""
+    """Delegates to the active controller, that is recorded at rf_type."""
     try:
       return getattr(self.controllers[self.rf_type], name)
     except:
@@ -47,11 +51,11 @@
       raise NotImplementedError
 
   def Initialize(self):
-    """Initialize the DUT device."""
+    """Initializes the DUT device."""
     raise NotImplementedError
 
   def Terminate(self):
-    """Terminate the DUT device."""
+    """Terminates the DUT device."""
     raise NotImplementedError
 
   def SetRF(self, rf_type):
@@ -60,96 +64,116 @@
     self.rf_type = rf_type
     self.controllers[self.rf_type].Initialize()
 
-  class ControllerBase(object):
-    """The abstract DUT controller class that every controller in DUT plugin
-    should inherit it. We use wrapped function for each API, that give us
-    flexibility to do some pre-processing or post-processing."""
+  class ControllerBase(device.ControllerBase):
+    """The abstract DUT RF controller class.
+
+    Every controller in DUT plugin should inherit it. We use wrapped function
+    for each API, that give us flexibility to do pre-processing or
+    post-processing.
+    """
 
     def __init__(self, dut=None):
       self.dut = dut
 
     def Initialize(self):
-      """Initialize the controller."""
       return self._Initialize()
 
     def _Initialize(self):
+      """Initializes the controller."""
       raise NotImplementedError
 
     def Terminate(self):
-      """Disconnect/unconfigure the interface that was being used."""
       return self._Terminate()
 
     def _Terminate(self):
+      """Disconnects/unconfigures the interface that was being used."""
       raise NotImplementedError
 
     def TxConfig(self, test):
-      """The test case details are passed in the test_params dictionary.
-      However, we can decide to have other parameters in case someone
-      wants to override (Not sure if we will keep these parameters going ahead).
-
-      If the test_params is NULL/False, then the rest of the parameters
-      can be used
-      """
-      return self._TxConfig(**test.ToDict())
+      test_case = self._CheckTestArgument(test.ToDict(), 'TX')
+      return self._TxConfig(**test_case)
 
     def _TxConfig(self, **kwargs):
+      """Configures the DUT for the test case.
+
+      Configures the transmission settings to the DUT without arming trigger.
+      """
       raise NotImplementedError
 
     def TxStart(self, test):
-      """Start the TX on the interface.
+      test_case = self._CheckTestArgument(test.ToDict(), 'TX')
+      return self._TxStart(**test_case)
 
-      NOTE: Its up to the plugin to block until its ready to transmit.
+    def _TxStart(self, **kwargs):
+      """Starts the TX on the interface.
+
+      NOTE: It is up to the plugin to block until its ready to transmit.
       The graphyte is not going to wait until the DUT is ready to transfer.
       It assumes that the interface is ready when this call returns.
       """
-      return self._TxStart(**test.ToDict())
-
-    def _TxStart(self, **kwargs):
       raise NotImplementedError
 
     def TxStop(self, test):
-      """Stop the TX."""
-      return self._TxStop(**test.ToDict())
+      test_case = self._CheckTestArgument(test.ToDict(), 'TX')
+      return self._TxStop(**test_case)
 
     def _TxStop(self, **kwargs):
+      """Stops the TX."""
       raise NotImplementedError
 
     def RxConfig(self, test):
-      return self._RxConfig(**test.ToDict())
+      test_case = self._CheckTestArgument(test.ToDict(), 'RX')
+      return self._RxConfig(**test_case)
 
     def _RxConfig(self, **kwargs):
+      """Configures the DUT for the receiving test case."""
       raise NotImplementedError
 
     def RxClearResult(self, test):
-      return self._RxClearResult(**test.ToDict())
+      test_case = self._CheckTestArgument(test.ToDict(), 'RX')
+      return self._RxClearResult(**test_case)
 
     def _RxClearResult(self, **kwargs):
+      """Measures the signal transmitted by the instrument.
+
+      The method would be called before the instrument starts transmitting
+      signal.
+      """
       raise NotImplementedError
 
     def RxGetResult(self, test):
-      results = self._RxGetResult(**test.ToDict())
+      test_case = self._CheckTestArgument(test.ToDict(), 'RX')
+      results = self._RxGetResult(**test_case)
       return (test.CheckTestPasses(results), results)
 
     def _RxGetResult(self, result_limit, **kwargs):
+      """Returns the test result of the test case.
+
+      Retrieves the outcome of each required result. The keys of the returned
+      value should be contain all the keys of the result_limit. The method would
+      be called after the instrument finish transmitting signal.
+      """
       raise NotImplementedError
 
   class WlanControllerBase(ControllerBase):
-    def _TxConfig(self, component_name, rf_type, test_type, center_freq,
+    RF_TYPE = 'WLAN'
+
+    def _TxConfig(self, component_name, center_freq,
                   power_level, standard, bandwidth, data_rate, chain_mask, nss,
                   long_preamble, **kwargs):
       raise NotImplementedError
 
-    def _TxStart(self, component_name, rf_type, test_type, center_freq,
+    def _TxStart(self, component_name, center_freq,
                  power_level, standard, bandwidth, data_rate, chain_mask, nss,
                  long_preamble, **kwargs):
       raise NotImplementedError
 
-    def _RxConfig(self, component_name, rf_type, test_type, center_freq,
+    def _RxConfig(self, component_name, center_freq,
                   power_level, standard, bandwidth, data_rate, chain_mask, nss,
                   long_preamble, rx_num_packets, **kwargs):
       raise NotImplementedError
 
-    def _RxClearResult(self, component_name, rf_type, test_type, center_freq,
+    def _RxClearResult(self, component_name, center_freq,
                        power_level, standard, bandwidth, data_rate, chain_mask,
                        nss, long_preamble, rx_num_packets, **kwargs):
       raise NotImplementedError
@@ -160,43 +184,47 @@
       raise NotImplementedError
 
   class BluetoothControllerBase(ControllerBase):
-    def _TxConfig(self, component_name, rf_type, test_type, center_freq,
+    RF_TYPE = 'BLUETOOTH'
+
+    def _TxConfig(self, component_name, center_freq,
                   power_level, packet_type, bit_pattern, **kwargs):
       raise NotImplementedError
 
-    def _TxStart(self, component_name, rf_type, test_type, center_freq,
+    def _TxStart(self, component_name, center_freq,
                  power_level, packet_type, bit_pattern, **kwargs):
       raise NotImplementedError
 
-    def _RxConfig(self, component_name, rf_type, test_type, center_freq,
+    def _RxConfig(self, component_name, center_freq,
                   power_level, packet_type, bit_pattern,
                   rx_num_packets=None, rx_num_bits=None, **kwargs):
       raise NotImplementedError
 
-    def _RxClearResult(self, component_name, rf_type, test_type, center_freq,
+    def _RxClearResult(self, component_name, center_freq,
                        power_level, packet_type, bit_pattern,
                        rx_num_packets=None, rx_num_bits=None, **kwargs):
       raise NotImplementedError
 
-    def _RxGetResult(self, component_name, rf_type, test_type, center_freq,
+    def _RxGetResult(self, component_name, center_freq,
                      power_level, packet_type, bit_pattern,
                      rx_num_packets=None, rx_num_bits=None, **kwargs):
       raise NotImplementedError
 
   class ZigbeeControllerBase(ControllerBase):
-    def _TxConfig(self, component_name, rf_type, test_type, center_freq,
+    RF_TYPE = '802_15_4'
+
+    def _TxConfig(self, component_name, center_freq,
                   power_level, **kwargs):
       raise NotImplementedError
 
-    def _TxStart(self, component_name, rf_type, test_type, center_freq,
+    def _TxStart(self, component_name, center_freq,
                  power_level, **kwargs):
       raise NotImplementedError
 
-    def _RxConfig(self, component_name, rf_type, test_type, center_freq,
+    def _RxConfig(self, component_name, center_freq,
                   power_level, rx_num_packets, **kwargs):
       raise NotImplementedError
 
-    def _RxClearResult(self, component_name, rf_type, test_type, center_freq,
+    def _RxClearResult(self, component_name, center_freq,
                        power_level, rx_num_packets, **kwargs):
       raise NotImplementedError
 
diff --git a/graphyte/dut/sample/dummy_dut.py b/graphyte/dut/sample/dummy_dut.py
index 456ca83..32ebc20 100644
--- a/graphyte/dut/sample/dummy_dut.py
+++ b/graphyte/dut/sample/dummy_dut.py
@@ -34,12 +34,12 @@
     def _Terminate(self):
       logger.info('DUT Wlan Terminate')
 
-    def _TxConfig(self, component_name, rf_type, test_type, center_freq,
+    def _TxConfig(self, component_name, center_freq,
                   power_level, standard, bandwidth, data_rate, chain_mask, nss,
                   long_preamble, **kwargs):
       logger.info('DUT Wlan TxConfig')
 
-    def _TxStart(self, component_name, rf_type, test_type, center_freq,
+    def _TxStart(self, component_name, center_freq,
                  power_level, standard, bandwidth, data_rate, chain_mask, nss,
                  long_preamble, **kwargs):
       logger.info('DUT Wlan TxStart')
@@ -47,12 +47,12 @@
     def _TxStop(self, **kwargs):
       logger.info('DUT Wlan TxStop')
 
-    def _RxConfig(self, component_name, rf_type, test_type, center_freq,
+    def _RxConfig(self, component_name, center_freq,
                   power_level, standard, bandwidth, data_rate, chain_mask, nss,
                   long_preamble, rx_num_packets, **kwargs):
       logger.info('DUT Wlan RxConfig')
 
-    def _RxClearResult(self, component_name, rf_type, test_type, center_freq,
+    def _RxClearResult(self, component_name, center_freq,
                        power_level, standard, bandwidth, data_rate, chain_mask,
                        nss, long_preamble, rx_num_packets, **kwargs):
       logger.info('DUT Wlan RxClearResult')
@@ -68,22 +68,22 @@
     def _Terminate(self):
       logger.info('DUT Bluetooth Terminate')
 
-    def _TxConfig(self, component_name, rf_type, test_type, center_freq,
+    def _TxConfig(self, component_name, center_freq,
                   power_level, packet_type, bit_pattern, **kwargs):
       logger.info('DUT Bluetooth TxConfig')
 
-    def _TxStart(self, component_name, rf_type, test_type, center_freq,
+    def _TxStart(self, component_name, center_freq,
                  power_level, packet_type, bit_pattern, **kwargs):
       logger.info('DUT Bluetooth TxStart')
 
     def _TxStop(self, **kwargs):
       logger.info('DUT Bluetooth TxStop')
 
-    def _RxConfig(self, component_name, rf_type, test_type, center_freq,
+    def _RxConfig(self, component_name, center_freq,
                   power_level, packet_type, bit_pattern, **kwargs):
       logger.info('DUT Bluetooth RxConfig')
 
-    def _RxClearResult(self, component_name, rf_type, test_type, center_freq,
+    def _RxClearResult(self, component_name, center_freq,
                        power_level, packet_type, bit_pattern, **kwargs):
       logger.info('DUT Bluetooth RxClearResult')
 
@@ -98,22 +98,22 @@
     def _Terminate(self):
       logger.info('DUT Zigbee Terminate')
 
-    def _TxConfig(self, component_name, rf_type, test_type, center_freq,
+    def _TxConfig(self, component_name, center_freq,
                   power_level, **kwargs):
       logger.info('DUT Zigbee TxConfig')
 
-    def _TxStart(self, component_name, rf_type, test_type, center_freq,
+    def _TxStart(self, component_name, center_freq,
                  power_level, **kwargs):
       logger.info('DUT Zigbee TxStart')
 
     def _TxStop(self, **kwargs):
       logger.info('DUT Zigbee TxStop')
 
-    def _RxConfig(self, component_name, rf_type, test_type, center_freq,
+    def _RxConfig(self, component_name, center_freq,
                   power_level, rx_num_packets, **kwargs):
       logger.info('DUT Zigbee RxConfig')
 
-    def _RxClearResult(self, component_name, rf_type, test_type, center_freq,
+    def _RxClearResult(self, component_name, center_freq,
                        power_level, rx_num_packets, **kwargs):
       logger.info('DUT Zigbee RxClearResult')
 
diff --git a/graphyte/graphyte.py b/graphyte/graphyte.py
index c214728..8b38f2f 100644
--- a/graphyte/graphyte.py
+++ b/graphyte/graphyte.py
@@ -33,11 +33,13 @@
 
 class Graphyte(object):
   """The graphyte module.
+
   Instantiating the class does everything now. Refer to the constructor below.
   """
   def __init__(self, config_file=None, log_file=None, result_file=None,
                verbose=False, console_output=False, append_mode=False):
     """The constructor for this module does most of it right now.
+
     - Load the graphyte.settings file to find the modules to load.
     - Load the plugins
     - Load test plans
@@ -149,6 +151,7 @@
 
   def Run(self):
     """The main method of the class.
+
     It returns whether all tests are passed or not.
     """
     self.all_tests_pass = True
diff --git a/graphyte/inst/__init__.py b/graphyte/inst/__init__.py
index d9c1d24..d360d9a 100644
--- a/graphyte/inst/__init__.py
+++ b/graphyte/inst/__init__.py
@@ -5,19 +5,23 @@
 # found in the LICENSE file.
 
 """The Virtual Instrument module.
+
 This is the virtual instrument class which every instrument plugin should
 implement.
 """
 
 from .. import link
 from ..default_setting import logger
+from .. import device
 
 
 class InstBase(object):
-  """The abstract instrument class that every instrument plugin should inherit
-  it. It contains several RF controllers, and each controller corresponds one RF
-  chip. We can control different RF chip by assigning the rf_type, and delegate
-  to the assigned controller."""
+  """The abstract instrument class.
+
+  Every instrument plugin should inherit it. It contains several RF controllers,
+  and each controller corresponds one RF chip. We can control different RF chip
+  by assigning the rf_type, and delegate to the assigned controller.
+  """
 
   name = 'Virtual instrument Plugin'
   need_link = False
@@ -45,7 +49,7 @@
     self.active_component = (None, None)
 
   def __getattr__(self, name):
-    """Delegate to the active controller, that is recorded at rf_type."""
+    """Delegates to the active controller, that is recorded at rf_type."""
     try:
       return getattr(self.controllers[self.rf_type], name)
     except:
@@ -59,20 +63,26 @@
     self.controllers[self.rf_type].Initialize()
 
   def Initialize(self):
-    """Initialize the instrument.
+    """Initializes the instrument.
 
     The method would be called only once before all tests items are executed.
     """
     raise NotImplementedError
 
   def Terminate(self):
-    """Terminate the instrument.
+    """Terminates the instrument.
 
     The method would be called only once after all tests items are executed.
     """
     raise NotImplementedError
 
   def SelfCalibrate(self, calibration_type='full'):
+    """Runs the instrument self calirbation.
+
+    Runs the internal calculation to correct for power measurement inaccuracies
+    in the case of temperature drift. This method would be called once before
+    all test cases starts.
+    """
     raise NotImplementedError
 
   def InitPortConfig(self, port_config_table):
@@ -97,7 +107,8 @@
     self._SetPortConfig(port_mapping, pathloss)
 
   def _SetPortConfig(self, port_mapping, pathloss):
-    """Set the port mapping and the pathloss table for the active component.
+    """Sets the port mapping and the pathloss table for the active component.
+
     Because a component might be multiple antenna, the port mapping and the path
     loss are the list.
     Arg:
@@ -114,53 +125,82 @@
     raise NotImplementedError
 
   def LockInstrument(self):
+    """Locks the instrument to reject other connection.
+
+    This method is used for the ping pong test. After calling this method, the
+    instrument should reject additional connections.
+    """
     raise NotImplementedError
 
   def UnlockInstrument(self):
+    """Unlocks the instrument to allow other connection.
+
+    This method should be called after LockInstrument is called.
+    After calling this method, the instrument should allow other connections.
+    """
     raise NotImplementedError
 
-  class ControllerBase(object):
+  class ControllerBase(device.ControllerBase):
+    """The abstract instrument RF controller class.
+
+    Every controller in instrument plugin should inherit it. We use wrapped
+    function for each API, that give us flexibility to do pre-processing or
+    post-processing.
+    """
     def __init__(self, inst=None):
       self.inst = inst
 
     def Initialize(self):
-      """Initialize the RF interface."""
       return self._Initialize()
 
     def _Initialize(self):
+      """Initializes the RF interface."""
       raise NotImplementedError
 
     def Terminate(self):
-      """Disconnect/unconfigure the interface that was being used."""
       return self._Terminate()
 
-    def _Terminate(self, **kwargs):
+    def _Terminate(self):
+      """Disconnects/unconfigures the interface that was being used."""
       raise NotImplementedError
 
     def TxConfig(self, test):
-      return self._TxConfig(**test.ToDict())
+      test_case = self._CheckTestArgument(test.ToDict(), 'TX')
+      return self._TxConfig(**test_case)
 
     def _TxConfig(self, **kwargs):
+      """Configures the instrument for the test case.
+
+      Configures measurement and commits settings to the instrument without
+      arming trigger. The method would be called before the DUT start
+      transmitting signal.
+      """
       raise NotImplementedError
 
     def TxMeasure(self, test):
-      return self._TxMeasure(**test.ToDict())
+      test_case = self._CheckTestArgument(test.ToDict(), 'TX')
+      return self._TxMeasure(**test_case)
 
     def _TxMeasure(self, **kwargs):
+      """Measures the Tx signal transmitted by DUT.
+
+      Triggers, captures, and analyzes the signal. The method would be called
+      after the DUT start transmitting signal.
+      """
       raise NotImplementedError
 
     def TxGetResult(self, test):
-      results = self._TxGetResult(**test.ToDict())
+      test_case = self._CheckTestArgument(test.ToDict(), 'TX')
+      results = self._TxGetResult(**test_case)
       # TODO(akahuang): Check the structure of the results.
       return (test.CheckTestPasses(results), results)
 
     def _TxGetResult(self, result_limit, **kwargs):
-      """Wait for measurement to be completed and return the test result.
+      """Waits for measurement to be completed and returns the test result.
 
       Args:
-        result_limit: A dict of the test result.
-        The values are a tuple of the lower bound and upper bound.
-        Example:
+        result_limit: A dict of the test result. The values are a tuple of the
+        lower bound and upper bound. For example:
           {
             'test_result1': (None, -25),
             'test_result2': (16, 20)
@@ -192,24 +232,36 @@
       raise NotImplementedError
 
     def RxConfig(self, test):
-      return self._RxConfig(**test.ToDict())
+      test_case = self._CheckTestArgument(test.ToDict(), 'RX')
+      return self._RxConfig(**test_case)
 
     def _RxConfig(self, **kwargs):
+      """Configures the instrument for the test case.
+
+      Configures the VSG and loads the waveform based on the signal information.
+      The method would be called before the DUT start receiving signal.
+      """
       raise NotImplementedError
 
     def RxGenerate(self, test):
-      return self._RxGenerate(**test.ToDict())
+      test_case = self._CheckTestArgument(test.ToDict(), 'RX')
+      return self._RxGenerate(**test_case)
 
     def _RxGenerate(self, rx_num_packets, power_level, **kwargs):
+      """Generates the signal and starts transmission."""
       raise NotImplementedError
 
     def RxStop(self, test):
-      return self._RxStop(**test.ToDict())
+      test_case = self._CheckTestArgument(test.ToDict(), 'RX')
+      return self._RxStop(**test_case)
 
     def _RxStop(self, **kwargs):
+      """Stops transmitting the signal."""
       raise NotImplementedError
 
   class WlanControllerBase(ControllerBase):
+    RF_TYPE = 'WLAN'
+
     def _TxConfig(self, component_name, rf_type, test_type, center_freq,
                   power_level, standard, bandwidth, data_rate, chain_mask, nss,
                   long_preamble, **kwargs):
@@ -236,6 +288,8 @@
       raise NotImplementedError
 
   class BluetoothControllerBase(ControllerBase):
+    RF_TYPE = 'BLUETOOTH'
+
     def __init__(self, inst):
       InstBase.ControllerBase.__init__(self, inst)
       self.inst = inst
@@ -253,7 +307,7 @@
       raise NotImplementedError
 
     def TxGetResult(self, test):
-      """Calculate Bluetooth Tx result.
+      """Calculates Bluetooth Tx result.
 
       delta_f2_f1_avg_ratio is the ratio of delta_f2_avg and delta_f1_avg, but
       two results come from different bit pattern, F0 and AA. So we measure both
@@ -306,6 +360,8 @@
       raise NotImplementedError
 
   class ZigbeeControllerBase(ControllerBase):
+    RF_TYPE = '802_15_4'
+
     def _TxConfig(self, component_name, rf_type, test_type, center_freq,
                   power_level, **kwargs):
       raise NotImplementedError
diff --git a/graphyte/inst/sample/dummy_inst.py b/graphyte/inst/sample/dummy_inst.py
index d8dd718..07590bd 100644
--- a/graphyte/inst/sample/dummy_inst.py
+++ b/graphyte/inst/sample/dummy_inst.py
@@ -52,18 +52,18 @@
     def _Terminate(self):
       logger.info('Inst WLAN Terminate')
 
-    def _TxConfig(self, component_name, rf_type, test_type, center_freq,
+    def _TxConfig(self, component_name, center_freq,
                   power_level, standard, bandwidth, data_rate, chain_mask, nss,
                   long_preamble, **kwargs):
       logger.info('Wlan TxConfig')
       self.chain_list = ChainMaskToList(kwargs.get('chain_mask'))
 
-    def _TxMeasure(self, component_name, rf_type, test_type, center_freq,
+    def _TxMeasure(self, component_name, center_freq,
                    power_level, standard, bandwidth, data_rate, chain_mask,
                    nss, long_preamble, result_limit, **kwargs):
       logger.info('Wlan TxMeasure')
 
-    def _TxGetResult(self, component_name, rf_type, test_type, center_freq,
+    def _TxGetResult(self, component_name, center_freq,
                      power_level, standard, bandwidth, data_rate, chain_mask,
                      nss, long_preamble, result_limit, **kwargs):
       logger.info('Wlan TxGetResult. Result limit: %s', result_limit)
@@ -73,12 +73,12 @@
           result[key] = {idx: value for idx in self.chain_list}
       return result
 
-    def _RxConfig(self, component_name, rf_type, test_type, center_freq,
+    def _RxConfig(self, component_name, center_freq,
                   power_level, standard, bandwidth, data_rate, chain_mask, nss,
                   long_preamble, rx_num_packets, **kwargs):
       logger.info('Wlan RxConfig')
 
-    def _RxGenerate(self, component_name, rf_type, test_type, center_freq,
+    def _RxGenerate(self, component_name, center_freq,
                     power_level, standard, bandwidth, data_rate, chain_mask,
                     nss, long_preamble, rx_num_packets, **kwargs):
       logger.info('Wlan RxGenerate. Rx num packets: %s, power level: %s',
@@ -94,26 +94,26 @@
     def _Terminate(self):
       logger.info('Inst Bluetooth Terminate')
 
-    def _TxConfig(self, component_name, rf_type, test_type, center_freq,
+    def _TxConfig(self, component_name, center_freq,
                   power_level, packet_type, bit_pattern, **kwargs):
       logger.info('Bluetooth TxConfig')
 
-    def _TxMeasure(self, component_name, rf_type, test_type, center_freq,
+    def _TxMeasure(self, component_name, center_freq,
                    power_level, packet_type, bit_pattern, result_limit,
                    **kwargs):
       logger.info('Bluetooth TxMeasure')
 
-    def _TxGetResult(self, component_name, rf_type, test_type, center_freq,
+    def _TxGetResult(self, component_name, center_freq,
                      power_level, packet_type, bit_pattern, result_limit,
                      **kwargs):
       logger.info('Bluetooth TxGetResult. Result limit: %s', result_limit)
       return MakeMockPassResult(result_limit)
 
-    def _RxConfig(self, component_name, rf_type, test_type, center_freq,
+    def _RxConfig(self, component_name, center_freq,
                   power_level, packet_type, bit_pattern, **kwargs):
       logger.info('Bluetooth RxConfig')
 
-    def _RxGenerate(self, component_name, rf_type, test_type, center_freq,
+    def _RxGenerate(self, component_name, center_freq,
                     power_level, packet_type, bit_pattern, **kwargs):
       logger.info('Bluetooth RxGenerate. power level: %s', power_level)
 
@@ -127,24 +127,24 @@
     def _Terminate(self):
       logger.info('Inst Zigbee Terminate')
 
-    def _TxConfig(self, component_name, rf_type, test_type, center_freq,
+    def _TxConfig(self, component_name, center_freq,
                   power_level, **kwargs):
       logger.info('Zigbee TxConfig')
 
-    def _TxMeasure(self, component_name, rf_type, test_type, center_freq,
+    def _TxMeasure(self, component_name, center_freq,
                    power_level, result_limit, **kwargs):
       logger.info('Zigbee TxMeasure')
 
-    def _TxGetResult(self, component_name, rf_type, test_type, center_freq,
+    def _TxGetResult(self, component_name, center_freq,
                      power_level, result_limit, **kwargs):
       logger.info('Zigbee TxGetResult. Result limit: %s', result_limit)
       return MakeMockPassResult(result_limit)
 
-    def _RxConfig(self, component_name, rf_type, test_type, center_freq,
+    def _RxConfig(self, component_name, center_freq,
                   power_level, rx_num_packets, **kwargs):
       logger.info('Zigbee RxConfig')
 
-    def _RxGenerate(self, component_name, rf_type, test_type, center_freq,
+    def _RxGenerate(self, component_name, center_freq,
                     power_level, rx_num_packets, **kwargs):
       logger.info('Zigbee RxGenerate. Rx num packets: %s, power level: %s',
                   rx_num_packets, power_level)
diff --git a/graphyte/port_config.py b/graphyte/port_config.py
index 44d16d7..7562da0 100755
--- a/graphyte/port_config.py
+++ b/graphyte/port_config.py
@@ -4,7 +4,8 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-"""Handle the port config, including the port mapping and the pathloss.
+"""Handles the port config, including the port mapping and the pathloss.
+
 We load the port config from json file, which format is:
 {
   <component_name>: [ // List is represented for the multiple antenna
@@ -20,17 +21,20 @@
     }
   ]
 }
+
 Then we load the pathloss from the corresponding csv file.
-The format of csv is
+The format of csv is:
   'title',   <frequency 1>, <frequency 2>, ...
   <title 1>, [pathloss 1],  [pathloss 2],  ...
   <title 2>, [pathloss 1],  [pathloss 2],  ...
+
 If the value is empty, we just ignore it. For example:
   'title',2402,2404,2406
   'path1',20.0,,19.9
   'path2',21.0,20.3,
+
 It means that path1 is {2402: 20.0, 2406: 19.9},
-path2 is {2402: 21.0, 2404: 20.3}
+path2 is {2402: 21.0, 2404: 20.3}.
 """
 
 import csv
@@ -82,8 +86,11 @@
     return self._pathloss_table[filename][title]
 
   def _ConvertPathloss(self, pathloss):
-    """Filter the empty entry, then convert the frequency to int, and convert
-    pathloss to float."""
+    """Converts a dict to a PathlossTable.
+
+    Filters the empty entry, converts the frequency to int, and converts
+    pathloss to float.
+    """
     ret = {}
     for key, value in pathloss.iteritems():
       if not value:
@@ -92,10 +99,12 @@
     return PathlossTable(ret)
 
   def QueryPortConfig(self, component_name, test_type):
-    """Return the port config of the certain component.
+    """Returns the port config of the certain component.
+
     Args:
       component_name: the coponent name.
       test_type: 'TX' or 'RX'
+
     Return:
       List of the port config, for multiple antenna.
     """
@@ -131,6 +140,7 @@
 
   The format is a dict which key is frequency unit in MHz, and the value is
   power loss in dB.
+
   Usage:
     table = PathlossTable({2000: 1.0, 2400: 3.1})
     pathloss = table[2014]
@@ -142,7 +152,7 @@
     return len(self.table) > 0
 
   def __getitem__(self, freq):
-    """Return the pathloss of the frequency.
+    """Returns the pathloss of the frequency.
 
     If the frequency is recorded at the table, then return the value directly.
     If not, calculate the value using the linear interpolation with the nearest
diff --git a/graphyte/result_writer.py b/graphyte/result_writer.py
index 5d3cf78..af4b9c8 100644
--- a/graphyte/result_writer.py
+++ b/graphyte/result_writer.py
@@ -26,7 +26,7 @@
     self.fout.close()
 
   def WriteResult(self, test_case, result):
-    """Write the test result to csv file.
+    """Writes the test result to csv file.
 
     For the multi-antenna case, we record the result of each antenna separately.
     Then the result value is a number, not a dictionary.
@@ -34,6 +34,7 @@
     For example:
       test_case: "WLAN TX ANTENNA-01"
       result: {"avg_power" : {0: 10.4, 1:11.2}}
+
     Then we will output two lines which test_name, result_name and value are:
       "WLAN TX ANTENNA-01-0", "avg_power", 10.4
       "WLAN TX ANTENNA-01-1", "avg_power", 11.2
diff --git a/graphyte/testplan.py b/graphyte/testplan.py
index 5f63f87..9480d11 100755
--- a/graphyte/testplan.py
+++ b/graphyte/testplan.py
@@ -50,7 +50,7 @@
 
 
 class TestPlan(object):
-  """Generate the test plan from CSV file.
+  """Generates the test plan from CSV file.
 
   The class parses the CSV file and generates a list of test cases.
 
@@ -69,7 +69,7 @@
       self.LoadConfigFile(config_file, search_dirs)
 
   def __len__(self):
-    """Return the count of the test cases.
+    """Returns the count of the test cases.
 
     we implement __len__ and __getitem__ to make TestPlan behave like a
     read-only list.
@@ -160,7 +160,7 @@
 
 
 def CreateTestCase(args, result_limit):
-  """Create the test case according to the RF type.
+  """Creates the test case according to the RF type.
 
   Since the verification and the generation of the test case for each RF type
   are slightly different, we use the simple factory pattern to create the test
@@ -169,6 +169,7 @@
   Args:
     args: the arguments of the test case.
     result_limit: the result limit of the test case.
+
   Return:
     a list of the test case.
   """
@@ -195,7 +196,7 @@
     return self._Create(args, result_limit)
 
   def _VerifyArgAndResult(self, args, result_limit):
-    """Verify the test case is valid or not.
+    """Verifies the test case is valid or not.
 
     1. Check the RF type is correct.
     2. Check all required arguments exist and are valid.
@@ -226,7 +227,7 @@
 
   @staticmethod
   def VerifyArguments(checker_dict, args):
-    """Verify all arguments are valid.
+    """Verifies all arguments are valid.
 
     If the keys of args are not the same as checker_dict, or there is any value
     is not valid, then raise the ValueError exception.
@@ -239,6 +240,7 @@
           'test_type': ListChecker(['TX', 'RX'])
         }
       args: the arguments of the test case.
+
     Raises:
       ValueError if args does not pass the verification.
     """
@@ -257,7 +259,7 @@
 
   @staticmethod
   def _VerifyResults(result_list, result_limit):
-    """Verify all results are valid.
+    """Verifies all results are valid.
 
     If there is key of result_limit not in result_list, or the value is not
     valid, then raise the ValueError exception.
@@ -265,6 +267,7 @@
     Args:
       result_list: a list of all valid result keys.
       result_limit: the result limit of the test case.
+
     Raises:
       ValueError if data is not passed the verification.
     """
@@ -393,10 +396,11 @@
       '3DH5': 1021}
 
   def _DetermineFormat(self, packet_type):
-    """Determine the bluetooth format of the packet type.
+    """Determines the bluetooth format of the packet type.
 
     Args:
       packet_type: the Bluetooth packet type.
+
     Returns:
       one of 'LE', 'BDR', or 'EDR'.
     """
@@ -434,7 +438,7 @@
     TestCaseFactory._VerifyResults(result_list, result_limit)
 
   def _Create(self, args, result_limit):
-    """Create the bluetooth test case.
+    """Creates the bluetooth test case.
 
     For BDR and LE, the bit pattern of the packet are different from results.
     We add the 'bit_pattern' argument and split into different test cases.
@@ -505,7 +509,7 @@
   """The test case. It contains the arguments of a RF test."""
 
   def __init__(self, name, args, result_limit):
-    """Initialize the test case.
+    """Initializes the test case.
 
     Arg:
       name: A string that should contain important arguments information.
@@ -613,7 +617,7 @@
 
 
 def StripRow(row):
-  """Strip every item in the row, and remove the right side of empty item."""
+  """Strips every item in the row, and remove the right side of empty item."""
   row = [item.strip() for item in row]
   while len(row) > 0 and len(row[-1]) == 0:
     row.pop()
diff --git a/graphyte/utils.py b/graphyte/utils.py
index b431047..b5c2c88 100644
--- a/graphyte/utils.py
+++ b/graphyte/utils.py
@@ -23,7 +23,7 @@
 
 
 def Enum(*args, **kwargs):
-  """Create the immutable enumeration set.
+  """Creates the immutable enumeration set.
 
   Usage:
     1. C-style enum. The value starts from 0 and increase orderly.
@@ -62,7 +62,8 @@
 
 
 def SearchConfig(filepath, search_dirs=None):
-  """Find the config file and return the content.
+  """Finds the config file and returns the content.
+
   The order of searching is:
   1. relative path
   2. config folder
@@ -82,7 +83,8 @@
 
 
 def PrepareOutputFile(file_path):
-  """ Confirm the output file path is ok.
+  """Confirms the output file path is ok.
+
   1. If the file_path is not absolute, then assign it to default log folder.
   2. Check if the directory exists. If not, create the folder first.
   """
@@ -105,8 +107,7 @@
   is closed if it still exists at that moment.
 
   Args:
-    Any allowable arguments to tempfile.mkstemp (e.g., prefix,
-      suffix, dir).
+    Any allowable arguments to tempfile.mkstemp (e.g., prefix, suffix, dir).
   """
   f, path = tempfile.mkstemp(**kwargs)
   os.close(f)
@@ -118,7 +119,7 @@
 
 
 def IsInBound(results, bound):
-  """Check the results meet the bound or not.
+  """Checks the results meet the bound or not.
 
   Args:
     results: A number for SISO case, or a dict for MIMO case. The values of the
@@ -150,7 +151,7 @@
 
 
 def MakeMockPassResult(result_limit):
-  """Make the result that pass all limit."""
+  """Makes the result that pass all limit."""
   def _MakeInBoundValue(bound):
     lower, upper = bound
     return lower or upper or 0
@@ -159,7 +160,7 @@
 
 
 def CalculateAverage(values, average_type='Linear'):
-  """Calculate the average value.
+  """Calculates the average value.
 
   Args:
     values: A list of float value.
@@ -192,7 +193,7 @@
 
 
 def CalculateAverageResult(results, average_type='Linear'):
-  """Calculate the average results.
+  """Calculates the average results.
 
   For WLAN multi-antenna case, the result would be a dict where the key is the
   antenna index. So we handle this kind of situation in this method.
@@ -266,7 +267,7 @@
 
 
 def WaitFor(condition, timeout_secs, poll_interval_secs=0.1):
-  """Wait for the given condition for at most the specified time.
+  """Waits for the given condition for at most the specified time.
 
   Args:
     condition: A function object.
@@ -302,7 +303,7 @@
 
 
 def Retry(max_retry_times, interval, target, condition=None, *args, **kwargs):
-  """Retry the function until the condition is satisfied.
+  """Retries the function until the condition is satisfied.
 
   Args:
     max_retry_times: the maximum retry times.