VOL-1058: Test Case: Authentication (RADIUS)

Apply review comment changes

Change-Id: I72b8dc9ff1cd4bd1c3570c6a7b84d49a1f0de55a
diff --git a/tests/atests/build/aaa_json b/tests/atests/build/aaa_json
new file mode 100644
index 0000000..491b594
--- /dev/null
+++ b/tests/atests/build/aaa_json
@@ -0,0 +1,24 @@
+{
+  "org.opencord.aaa":{
+    "AAA":{	
+  "radiusIp":"192.168.249.222",
+      "nasIp":"5.6.7.8",
+      "radiusServerPort":"1812",
+      "radiusSecret":"SECRET",
+      "bindings":[
+        {	
+          "mac":"de:ad:be:ef:ba:11",
+          "s-tag":2,
+          "c-tag":2,
+          "nas_port_id":"location"
+        },
+        {	
+          "mac":"de:ad:be:ef:ca:fe",
+          "s-tag":2,
+          "c-tag":122,
+          "nas_port_id":"location"
+        }
+      ]
+    }
+  }
+}
diff --git a/tests/atests/build/devices_json b/tests/atests/build/devices_json
index 6fbc4d5..74c0aca 100644
--- a/tests/atests/build/devices_json
+++ b/tests/atests/build/devices_json
@@ -1 +1,65 @@
-{"of:0001000000000005":{"basic":{"driver":"voltha"},"accessDevice":{"uplink":"0","vlan":"1004"}},"of:0001000000000006":{"basic":{"driver":"voltha"},"accessDevice":{"uplink":"0","vlan":"1005"}},"of:0001000000000003":{"basic":{"driver":"voltha"},"accessDevice":{"uplink":"0","vlan":"1002"}},"of:0001000000000004":{"basic":{"driver":"voltha"},"accessDevice":{"uplink":"0","vlan":"1003"}},"of:0000aabbccddeeff":{"basic":{"driver":"voltha"},"accessDevice":{"uplink":"0","vlan":"2"}},"of:0001000000000002":{"basic":{"driver":"voltha"},"accessDevice":{"uplink":"0","vlan":"1001"}},"of:0001aabbccddeeff":{"basic":{"driver":"voltha"},"accessDevice":{"uplink":"0","vlan":"2"}}}
+{
+  "of:0001000000000005":{
+    "basic":{
+      "driver":"voltha"
+    },
+    "accessDevice":{
+      "uplink":"0",
+      "vlan":"1004"
+    }
+  },
+  "of:0001000000000006":{
+    "basic":{
+      "driver":"voltha"
+    },
+    "accessDevice":{
+      "uplink":"0",
+      "vlan":"1005"
+    }
+  },
+  "of:0001000000000003":{
+    "basic":{
+      "driver":"voltha"
+    },
+    "accessDevice":{
+      "uplink":"0",
+      "vlan":"1002"
+    }
+  },
+  "of:0001000000000004":{
+    "basic":{
+      "driver":"voltha"
+    },
+    "accessDevice":{
+      "uplink":"0",
+      "vlan":"1003"
+    }
+  },
+  "of:0000aabbccddeeff":{
+    "basic":{
+      "driver":"voltha"
+    },
+    "accessDevice":{
+      "uplink":"0",
+      "vlan":"2"
+    }
+  },
+  "of:0001000000000002":{
+    "basic":{
+      "driver":"voltha"
+    },
+    "accessDevice":{
+      "uplink":"0",
+      "vlan":"1001"
+    }
+  },
+  "of:0001aabbccddeeff":{
+    "basic":{
+      "driver":"voltha"
+    },
+    "accessDevice":{
+      "uplink":"0",
+      "vlan":"2"
+    }
+  }
+}
diff --git a/tests/atests/build/sadis_json b/tests/atests/build/sadis_json
index fc613b7..fcded75 100644
--- a/tests/atests/build/sadis_json
+++ b/tests/atests/build/sadis_json
@@ -1,32 +1,31 @@
 {  
-   "org.opencord.sadis":{  
-      "sadis":{  
-         "integration":{  
-            "cache":{  
-               "enabled":true,
-               "maxsize":50,
-               "ttl":"PT1m"
-            }
-         },
-         "entries":[  
-            {  
-               "id":"PSMO12345678",
-               "cTag":33,
-               "sTag":44,
-               "nasPortId":"PSMO12345678"
-            },
-            {  
-               "id":"1d1d1d1d1d1d11",
-               "hardwareIdentifier":"00:1b:22:00:b1:78",
-               "ipAddress":"192.168.1.252",
-               "nasId":"B100-NASID"
-            },
-            {  
-               "id":"olt.voltha.svc:50060",
-               "uplinkPort":2
-            }
-         ]
-      }
-   }
+  "org.opencord.sadis":{  
+    "sadis":{  
+      "integration":{  
+        "cache":{  
+          "enabled":true,
+          "maxsize":50,
+          "ttl":"PT1m"
+        }
+      },
+      "entries":[  
+        {  
+          "id":"PSMO12345678",
+          "cTag":33,
+          "sTag":44,
+          "nasPortId":"PSMO12345678"
+        },
+        {  
+          "id":"1d1d1d1d1d1d11",
+          "hardwareIdentifier":"00:1b:22:00:b1:78",
+          "ipAddress":"192.168.1.252",
+          "nasId":"B100-NASID"
+        },
+        {  
+          "id":"olt.voltha.svc:50060",
+          "uplinkPort":2
+        }
+      ]
+    }
+  }
 }
-
diff --git a/tests/atests/common/authentication.py b/tests/atests/common/authentication.py
new file mode 100644
index 0000000..6bbc669
--- /dev/null
+++ b/tests/atests/common/authentication.py
@@ -0,0 +1,158 @@
+#
+# Copyright 2018 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+"""
+vOLT-HA Authentication Test Case module
+"""
+
+import time
+import os
+import subprocess
+import commands
+import testCaseUtils
+import logging
+import signal
+
+class Authentication(object):
+
+    """
+    This class implements voltha authentication test case
+    """
+    AUTHENTICATE_FILENAME = 'voltha_authenticate.log'
+    
+    def __init__(self):
+        self.dirs = {}
+        self.dirs ['log'] = None
+        self.dirs ['root'] = None
+        self.dirs ['voltha'] = None
+        
+        self.__rgName = None
+        self.__radiusName = None
+        self.__radiusIp = None
+        
+    def aSetLogDirs(self, rootDir, volthaDir, logDir):
+        testCaseUtils.configDirs(self, logDir, rootDir, volthaDir)
+
+    def discover_rg_pod_name(self):
+        self.__rgName = testCaseUtils.extractPodName('rg-').strip()
+         
+    def discover_freeradius_pod_name(self):
+        self.__radiusName = testCaseUtils.extractPodName('freeradius').strip()
+        logging.info ('freeradius Name = %s' % self.__radiusName)
+        
+    def discover_freeradius_ip_addr(self):
+        ipAddr = testCaseUtils.extractRadiusIpAddr(self.__radiusName)
+        assert ipAddr, 'No IP address listed for freeradius'
+        self.__radiusIp = ipAddr.strip()
+        logging.info('freeradius IP = %s' % self.__radiusIp)
+        
+    def set_current_freeradius_ip_in_aaa_json(self):
+        status = testCaseUtils.modifyRadiusIpInJsonUsingSed(self, self.__radiusIp)
+        assertFalse = 'Setting Radius Ip in Json File did not return Success'
+          
+    def alter_aaa_application_configuration_in_onos_using_aaa_json(self):
+        logging.info ('Altering the Onos NetCfg AAA apps with Freeradius IP address')
+        logging.debug ('curl --user karaf:karaf -X POST -H "Content-Type: application/json" '
+            'http://localhost:30120/onos/v1/network/configuration/apps/ -d @%s/tests/atests/build/aaa_json'
+            % testCaseUtils.getDir(self, 'voltha'))
+        os.system('curl --user karaf:karaf -X POST -H "Content-Type: application/json" '
+            'http://localhost:30120/onos/v1/network/configuration/apps/ -d @%s/tests/atests/build/aaa_json'
+            % testCaseUtils.getDir(self, 'voltha'))
+     
+    def execute_authenticatication_on_rg(self):
+        logging.info ('Running Radius Authentication from RG')
+        process_output = open('%s/%s' % (testCaseUtils.getDir(self, 'log'), self.AUTHENTICATE_FILENAME), 'w')
+        proc1 = subprocess.Popen(['/usr/bin/kubectl', 'exec', '-n', 'voltha', self.__rgName, '--', 'bash', '-c', \
+                                  '/sbin/wpa_supplicant -Dwired -ieth0 -c /etc/wpa_supplicant/wpa_supplicant.conf'],
+                                 stdout=process_output,
+                                 stderr=process_output)
+        time.sleep(15)
+        procPidSupplicant1 = subprocess.Popen(['/usr/bin/kubectl', 'exec', '-n', 'voltha', self.__rgName, '--', 'ps', '-ef'],
+                             stdout=subprocess.PIPE,
+                             stderr=subprocess.PIPE)
+        procPidSupplicant2 = subprocess.Popen(['grep', '-e', '/sbin/wpa_supplicant'], stdin=procPidSupplicant1.stdout,
+                             stdout=subprocess.PIPE,
+                             stderr=subprocess.PIPE)
+        procPidSupplicant3 = subprocess.Popen(['awk', "{print $2}"], stdin=procPidSupplicant2.stdout,
+                             stdout=subprocess.PIPE,
+                             stderr=subprocess.PIPE)
+
+        procPidSupplicant1.stdout.close()
+        procPidSupplicant2.stdout.close()
+
+        out, err = procPidSupplicant3.communicate()
+        supplicantPid = out.strip()
+        
+        procKillSupplicant1 = subprocess.Popen(['/usr/bin/kubectl', 'exec', '-n', 'voltha', self.__rgName, '--', 'kill', supplicantPid],
+                             stdout=subprocess.PIPE,
+                             stderr=subprocess.PIPE)
+        out, err = procKillSupplicant1.communicate()
+
+        procPidBash1 = subprocess.Popen(['/usr/bin/kubectl', 'exec', '-n', 'voltha', self.__rgName, '--', 'ps', '-ef'],
+                             stdout=subprocess.PIPE,
+                             stderr=subprocess.PIPE)
+        procPidBash2 = subprocess.Popen(['grep', '-e', '/bin/bash'], stdin=procPidBash1.stdout,
+                             stdout=subprocess.PIPE,
+                             stderr=subprocess.PIPE)
+        procPidBash3 = subprocess.Popen(['awk', "{print $2}"], stdin=procPidBash2.stdout,
+                             stdout=subprocess.PIPE,
+                             stderr=subprocess.PIPE)
+
+        procPidBash1.stdout.close()
+        procPidBash2.stdout.close()
+
+        out, err = procPidBash3.communicate()
+        bashPid = out.strip()
+        
+        procKillBash1 = subprocess.Popen(['/usr/bin/kubectl', 'exec', '-n', 'voltha', self.__rgName, '--', 'kill', '-9', bashPid],
+                             stdout=subprocess.PIPE,
+                             stderr=subprocess.PIPE)
+        out, err = procKillBash1.communicate()
+
+        process_output.close()       
+
+        testCaseUtils.printLogFile(self, self.AUTHENTICATE_FILENAME)
+        
+    def verify_authentication_should_have_started(self):
+        statusLines = testCaseUtils.get_fields_from_grep_command(self, 'CTRL-EVENT-EAP-STARTED', self.AUTHENTICATE_FILENAME)
+        assert statusLines, 'Authentication was not started'
+        
+    def verify_authentication_should_have_completed(self):
+        statusLines = testCaseUtils.get_fields_from_grep_command(self, 'CTRL-EVENT-EAP-SUCCESS', self.AUTHENTICATE_FILENAME)
+        assert statusLines, 'Authentication was not completed successfully'
+
+    def verify_authentication_should_have_disconnected(self):
+        statusLines = testCaseUtils.get_fields_from_grep_command(self, 'CTRL-EVENT-DISCONNECTED', self.AUTHENTICATE_FILENAME)
+        assert statusLines, 'Authentication was not disconnected'
+
+    def verify_authentication_should_have_terminated(self):
+        statusLines = testCaseUtils.get_fields_from_grep_command(self, 'CTRL-EVENT-TERMINATING', self.AUTHENTICATE_FILENAME)
+        assert statusLines, 'Authentication was not terminated'
+       
+def runTest(rootDir, volthaDir, logDir):
+    auth = Authentication()
+    auth.aSetLogDirs(rootDir, volthaDir, logDir)
+    auth.discover_rg_pod_name()
+    auth.discover_freeradius_pod_name()
+    auth.discover_freeradius_ip_addr()
+    auth.set_current_freeradius_ip_in_aaa_json()
+    auth.alter_aaa_application_configuration_in_onos_using_aaa_json()
+    auth.execute_authenticatication_on_rg()
+    auth.verify_authentication_should_have_started()
+    auth.verify_authentication_should_have_completed()
+    auth.verify_authentication_should_have_disconnected()
+    auth.verify_authentication_should_have_terminated()
+
diff --git a/tests/atests/common/auto_test.py b/tests/atests/common/auto_test.py
index e6d21db..2721923 100755
--- a/tests/atests/common/auto_test.py
+++ b/tests/atests/common/auto_test.py
@@ -25,13 +25,13 @@
 import volthaMngr
 import preprovisioning
 import discovery
+import authentication
 import logging
 
 DEFAULT_LOG_DIR = '/tmp/voltha_test_results'
 logging.basicConfig(level=logging.INFO)
 
-def dirInit(logDir=DEFAULT_LOG_DIR,
-         volthaDir=os.environ['VOLTHA_BASE']):
+def dir_init(logDir=DEFAULT_LOG_DIR, volthaDir=os.environ['VOLTHA_BASE']):
     logging.info(__file__)
     """
     Init automated testing environment and return three directories: root dir,
@@ -45,10 +45,10 @@
     # In future in order to keep the history of jobs, the run time should be
     # added to the log directory name
     # logDir += '_' + currentTime
-    
+ 
     os.system('mkdir -p ' + logDir + ' > /dev/null 2>&1')
     os.system('rm -rf %s/*' % logDir)
-    logging.info('Start Provisioning Test at: %s\nRoot Directory: %s\n'
+    logging.info('Starting Voltha Test Case Suite at: %s\nRoot Directory: %s\n'
           'VOLTHA Directory: %s\nLog Directory: %s' %
           (currentTime, rootDir, volthaDir, logDir))
 
@@ -68,12 +68,14 @@
                         help='log directory (default: %s).' % DEFAULT_LOG_DIR)
     args = parser.parse_args()
 
-    ROOT_DIR, VOLTHA_DIR, LOG_DIR = dirInit(args.logDir)
-
+    ROOT_DIR, VOLTHA_DIR, LOG_DIR = dir_init(args.logDir)
+    
     volthaMngr.voltha_Initialize(ROOT_DIR, VOLTHA_DIR, LOG_DIR)
 
     preprovisioning.runTest('olt.voltha.svc', 50060, 'ponsim_olt', 'ponsim_onu', LOG_DIR)
     
     discovery.runTest('ponsim_olt', 'ponsim_onu', LOG_DIR)
 
+    authentication.runTest(ROOT_DIR, VOLTHA_DIR, LOG_DIR)
+
     time.sleep(5)
diff --git a/tests/atests/common/testCaseUtils.py b/tests/atests/common/testCaseUtils.py
index ead244d..fe76687 100755
--- a/tests/atests/common/testCaseUtils.py
+++ b/tests/atests/common/testCaseUtils.py
@@ -105,7 +105,7 @@
         for line in lines:
             sys.stdout.write (line)
 
-def extractIpAddr(podName):
+def extractPodIpAddr(podName):
     proc1 = subprocess.Popen(['/usr/bin/kubectl', 'get', 'svc', '--all-namespaces'],
                              stdout=subprocess.PIPE,
                              stderr=subprocess.PIPE)
@@ -121,6 +121,22 @@
     out, err = proc3.communicate()
     return out
     
+def extractRadiusIpAddr(podName):
+    proc1 = subprocess.Popen(['/usr/bin/kubectl', 'describe', 'pod', '-n', 'voltha', podName],
+                             stdout=subprocess.PIPE,
+                             stderr=subprocess.PIPE)
+    proc2 = subprocess.Popen(['grep', '^IP:'], stdin=proc1.stdout,
+                             stdout=subprocess.PIPE,
+                             stderr=subprocess.PIPE)
+    proc3 = subprocess.Popen(['awk', "{print $2}"], stdin=proc2.stdout,
+                             stdout=subprocess.PIPE,
+                             stderr=subprocess.PIPE)
+                            
+    proc1.stdout.close
+    proc2.stdout.close
+    out, err = proc3.communicate()
+    return out
+    
 def extractPodName(shortPodName):
     proc1 = subprocess.Popen(['/usr/bin/kubectl', 'get', 'pods', '--all-namespaces'],
                              stdout=subprocess.PIPE,
@@ -137,4 +153,9 @@
     proc2.stdout.close
     out, err = proc3.communicate()
     return out
+    
+def modifyRadiusIpInJsonUsingSed(self, newIpAddr):
+    sedCommand ="sed -i '/radiusIp/c\  \"radiusIp\":\"'%s'\",' %s/tests/atests/build/aaa_json" % (newIpAddr, getDir(self, 'voltha'))
+    status = commands.getstatusoutput(sedCommand)[0]
+    return status
 
diff --git a/tests/atests/robot/voltha_automated_test_suite.robot b/tests/atests/robot/voltha_automated_test_suite.robot
index 66a15bd..60115eb 100755
--- a/tests/atests/robot/voltha_automated_test_suite.robot
+++ b/tests/atests/robot/voltha_automated_test_suite.robot
@@ -19,9 +19,11 @@
 Library           ../common/volthaMngr.py
 Library           ../common/preprovisioning.py
 Library           ../common/discovery.py
+Library           ../common/authentication.py
 Library           volthaMngr.VolthaMngr
 Library           preprovisioning.Preprovisioning
 Library           discovery.Discovery
+Library           authentication.Authentication
 
 Suite Setup        Start Voltha      
 Suite Teardown     Stop Voltha
@@ -71,12 +73,32 @@
     Olt Should Have At Least One Flow
     Onu Should Have At Least One Flow
     
+Radius Authentication
+    [Documentation]     Radius Authentication
+    ...                 This test attempts to perform a Radius Authentication from the RG
+    ...                 It uses the wpa_supplicant app to authenticate using EAPOL.
+    ...                 We then verify the generated log file confirming all the authentication steps
+    ASet Log Dirs    ${ROOT_DIR}    ${VOLTHA_DIR}    ${LOG_DIR}
+    Discover RG Pod Name
+    Discover Freeradius Pod Name
+    Discover Freeradius Ip Addr
+    Set Current Freeradius Ip In AAA Json
+    Alter AAA Application Configuration In Onos Using AAA Json
+    Execute Authenticatication On RG
+    Verify Authentication Should Have Started
+    Verify Authentication Should Have Completed
+    Verify Authentication Should Have Disconnected
+    Verify Authentication Should Have Terminated    
+
 *** Keywords ***
 Start Voltha
     [Documentation]     Start Voltha infrastructure to run test(s). This includes starting all 
     ...                 Kubernetes Pods and start collection of logs. PonsimV2 has now been
     ...                 containerized and does not need to be managed separately
     ${ROOT_DIR}  ${VOLTHA_DIR}  ${LOG_DIR}      Dir Init    ${LOG_DIR}
+    Set Suite Variable  ${ROOT_DIR}
+    Set Suite Variable  ${VOLTHA_DIR}
+    Set Suite Variable  ${LOG_DIR}   
     VSet Log Dirs  ${ROOT_DIR}    ${VOLTHA_DIR}    ${LOG_DIR}
     Stop Voltha
     Start All Pods