Support to enable VOLTHA in cord-tester.
VOLTHA can now be started by cord-tester by specifying voltha_loc in manifest file.
voltha_intf specifies the interface for voltha to listen.
A sample manifest-voltha.json can be modified accordingly before starting cord-tester.
Changed the default olt_type to simulated_olt in volthaTest configuration json.
This would enable testing of voltha tests.
Fix indentation broken in voltha tests earlier.

Change-Id: Ia18b870c83dcb60c15c07f8602579494f32457c9
diff --git a/src/test/setup/cord-test.py b/src/test/setup/cord-test.py
index 960e35f..a2d0ac3 100755
--- a/src/test/setup/cord-test.py
+++ b/src/test/setup/cord-test.py
@@ -30,6 +30,7 @@
 from CordContainer import *
 from CordTestServer import cord_test_server_start,cord_test_server_stop,cord_test_server_shutdown,CORD_TEST_HOST,CORD_TEST_PORT
 from TestManifest import TestManifest
+from VolthaCtrl import VolthaService
 from docker import Client
 from docker.utils import kwargs_from_env
 from Xos import XosServiceProfile
@@ -545,6 +546,8 @@
     service_profile = test_manifest.service_profile
     synchronizer = test_manifest.synchronizer
     olt_config_file = test_manifest.olt_config
+    voltha_loc = test_manifest.voltha_loc
+    voltha_intf = test_manifest.voltha_intf
     if not os.access(olt_config_file, os.F_OK):
         olt_config_file = os.path.join(CordTester.tester_base, 'olt_config.json')
     else:
@@ -661,6 +664,11 @@
                 OnosCtrl.install_app(args.app, onos_ip = ip)
         except: pass
 
+    if voltha_loc:
+        #start voltha
+        voltha = VolthaService(voltha_loc, onos_ips[0], interface = voltha_intf)
+        voltha.start()
+
     if radius_ip is None:
         ##Start Radius container
         radius = Radius(prefix = Container.IMAGE_PREFIX, update = update_map['radius'],
@@ -689,7 +697,8 @@
                      'LOG_LEVEL': test_manifest.log_level,
                      'HEAD_NODE': head_node if head_node else CORD_TEST_HOST,
                      'MAAS_API_KEY': maas_api_key,
-                     'KARAF_VERSION' : test_manifest.karaf_version
+                     'KARAF_VERSION' : test_manifest.karaf_version,
+                     'VOLTHA_ENABLED' : True if voltha_loc else False
                    }
 
     if ssh_key_file:
@@ -822,6 +831,8 @@
     iterations = test_manifest.iterations
     service_profile = test_manifest.service_profile
     synchronizer = test_manifest.synchronizer
+    voltha_loc = test_manifest.voltha_loc
+    voltha_intf = test_manifest.voltha_intf
     onos_cord = None
     onos_cord_loc = test_manifest.onos_cord
     Onos.update_data_dir(test_manifest.karaf_version)
@@ -929,6 +940,11 @@
             OnosCtrl.install_app(args.app, onos_ip = ip)
     except: pass
 
+    if voltha_loc:
+        #start voltha
+        voltha = VolthaService(voltha_loc, onos_ips[0], interface = voltha_intf)
+        voltha.start()
+
     ##Start Radius container if not started
     if radius_ip is None:
         radius = Radius(prefix = Container.IMAGE_PREFIX, update = update_map['radius'],
@@ -967,7 +983,8 @@
                          'LOG_LEVEL': test_manifest.log_level,
                          'HEAD_NODE': head_node if head_node else CORD_TEST_HOST,
                          'MAAS_API_KEY': maas_api_key,
-                         'KARAF_VERSION' : test_manifest.karaf_version
+                         'KARAF_VERSION' : test_manifest.karaf_version,
+                         'VOLTHA_ENABLED' : True if voltha_loc else False
                        }
 
         if ssh_key_file:
@@ -1023,6 +1040,7 @@
         args.onos_cord = manifest.onos_cord
         args.service_profile = manifest.service_profile
         args.synchronizer = manifest.synchronizer
+        args.voltha_loc = manifest.voltha_loc
     else:
         args.onos_ip = None
         args.radius_ip = None
@@ -1057,6 +1075,10 @@
     quagga_container = '{}{}:candidate'.format(prefix, Quagga.IMAGE)
     Container.cleanup(radius_container)
     Container.cleanup(quagga_container)
+    if args.voltha_loc:
+        voltha = VolthaService(args.voltha_loc, args.onos_ip)
+        voltha.stop()
+
     if args.onos_cord:
         #try restoring the onos cord instance
         try:
@@ -1280,6 +1302,11 @@
                             help='Specify the synchronizer to use for ONOS cord instance when running on podd.'
                             'Eg: vtn,fabric,cord')
     parser_run.add_argument('-karaf', '--karaf', default='3.0.8', type=str, help='Karaf version for ONOS')
+    parser_run.add_argument('-voltha-loc', '--voltha-loc', default='', type=str,
+                            help='Specify the voltha location in order to start voltha')
+    parser_run.add_argument('-voltha-intf', '--voltha-intf', default='eth0', type=str,
+                            help='Specify the voltha interface for voltha to listen')
+
     parser_run.set_defaults(func=runTest)
 
     parser_setup = subparser.add_parser('setup', help='Setup cord tester environment')
@@ -1323,6 +1350,10 @@
     parser_setup.add_argument('-jvm-heap-size', '--jvm-heap-size', default='', type=str, help='ONOS JVM heap size')
     parser_setup.add_argument('-network', '--network', default='', type=str, help='Docker network to attach')
     parser_setup.add_argument('-karaf', '--karaf', default='3.0.8', type=str, help='Karaf version for ONOS')
+    parser_setup.add_argument('-voltha-loc', '--voltha-loc', default='', type=str,
+                              help='Specify the voltha location in order to start voltha')
+    parser_setup.add_argument('-voltha-intf', '--voltha-intf', default='eth0', type=str,
+                              help='Specify the voltha interface for voltha to listen')
     parser_setup.set_defaults(func=setupCordTester)
 
     parser_xos = subparser.add_parser('xos', help='Building xos into cord tester environment')
@@ -1374,6 +1405,8 @@
                                 help='Specify the synchronizer to use for ONOS cord instance when running on podd.'
                                 'Eg: vtn,fabric,cord')
     parser_cleanup.add_argument('-m', '--manifest', default='', type=str, help='Provide test manifest')
+    parser_cleanup.add_argument('-voltha-loc', '--voltha-loc', default='', type=str,
+                                help='Specify the voltha location')
     parser_cleanup.set_defaults(func=cleanupTests)
 
     c = Client(**(kwargs_from_env()))
diff --git a/src/test/setup/manifest-voltha.json b/src/test/setup/manifest-voltha.json
new file mode 100644
index 0000000..d73b5d2
--- /dev/null
+++ b/src/test/setup/manifest-voltha.json
@@ -0,0 +1,11 @@
+{
+    "onos_instances": 1,
+    "olt": true,
+    "start_switch": true,
+    "onos_image": "onosproject/onos:latest",
+    "log_level" : "INFO",
+    "jvm_heap_size" : "1G",
+    "karaf_version" : "3.0.8",
+    "voltha_loc" : "/home/ubuntu/voltha/incubator/voltha",
+    "voltha_intf" : "enp0s9"
+}
diff --git a/src/test/utils/TestManifest.py b/src/test/utils/TestManifest.py
index bdd66c7..26c5130 100644
--- a/src/test/utils/TestManifest.py
+++ b/src/test/utils/TestManifest.py
@@ -50,6 +50,8 @@
             self.server = args.server
             self.jvm_heap_size = args.jvm_heap_size if args.jvm_heap_size else None
             self.karaf_version = args.karaf
+            self.voltha_loc = args.voltha_loc
+            self.voltha_intf = args.voltha_intf
         else:
             with open(self.manifest, 'r') as fd:
                 data = json.load(fd)
@@ -76,3 +78,5 @@
             self.iterations = data.get('iterations', None)
             self.jvm_heap_size = data.get('jvm_heap_size', None)
             self.karaf_version = data.get('karaf_version', '3.0.8')
+            self.voltha_loc = data.get('voltha_loc', '')
+            self.voltha_intf = data.get('voltha_intf', 'eth0')
diff --git a/src/test/utils/VolthaCtrl.py b/src/test/utils/VolthaCtrl.py
index b23aefa..19e246c 100644
--- a/src/test/utils/VolthaCtrl.py
+++ b/src/test/utils/VolthaCtrl.py
@@ -1,7 +1,93 @@
 import requests
 import json
 import time
-from CordTestUtils import log_test as log
+import os
+import signal
+from CordTestUtils import log_test as log, getstatusoutput
+from CordContainer import Container
+
+class VolthaService(object):
+    services = ('consul', 'kafka', 'zookeeper', 'registrator', 'fluentd')
+    compose_file = 'docker-compose-system-test.yml'
+    service_map = {}
+
+    def __init__(self, voltha_loc, controller, interface = 'eth0'):
+        if not os.access(voltha_loc, os.F_OK):
+            raise Exception('Voltha location %s not found' %voltha_loc)
+        compose_file_loc = os.path.join(voltha_loc, 'compose', self.compose_file)
+        if not os.access(compose_file_loc, os.F_OK):
+            raise Exception('Voltha compose file %s not found' %compose_file_loc)
+        self.voltha_loc = voltha_loc
+        self.controller = controller
+        self.interface = interface
+        self.compose_file_loc = compose_file_loc
+
+    def start(self):
+        start_cmd = 'docker-compose -f {} up -d {} {} {} {} {}'.format(self.compose_file_loc,
+                                                                       *self.services)
+        ret = os.system(start_cmd)
+        if ret != 0:
+            raise Exception('Failed to start voltha services. Failed with code %d' %ret)
+
+        for service in self.services:
+            name = 'compose_{}_1'.format(service)
+            network = 'compose_default'
+            cnt = Container(name, name)
+            ip = cnt.ip(network = network)
+            if not ip:
+                raise Exception('IP not found for container %s' %name)
+            print('IP %s for service %s' %(ip, service))
+            self.service_map[service] = dict(name = name, network = network, ip = ip)
+
+        #first start chameleon
+        chameleon_start_cmd = "cd {} && sh -c '. ./env.sh && \
+        nohup python chameleon/main.py -v --consul=localhost:8500 \
+        --fluentd={}:24224 --grpc-endpoint=localhost:50555 \
+        >/tmp/chameleon.log 2>&1 &'".format(self.voltha_loc,
+                                            self.service_map['fluentd']['ip'])
+        ret = os.system(chameleon_start_cmd)
+        if ret != 0:
+            raise Exception('VOLTHA chameleon service not started. Failed with return code %d' %ret)
+
+        #now start voltha and ofagent
+        voltha_start_cmd = "cd {} && sh -c '. ./env.sh && \
+        nohup python voltha/main.py -v --consul=localhost:8500 --kafka={}:9092 -I {} \
+        --fluentd={}:24224 --rest-port=8880 --grpc-port=50555 \
+        >/tmp/voltha.log 2>&1 &'".format(self.voltha_loc,
+                                         self.service_map['kafka']['ip'],
+                                         self.interface,
+                                         self.service_map['fluentd']['ip'])
+        ret = os.system(voltha_start_cmd)
+        if ret != 0:
+            raise Exception('Failed to start VOLTHA. Return code %d' %ret)
+
+
+        ofagent_start_cmd = "cd {} && sh -c '. ./env.sh && \
+        nohup python ofagent/main.py -v --consul=localhost:8500 \
+        --fluentd={}:24224 --controller={}:6653 --grpc-endpoint=localhost:50555 \
+        >/tmp/ofagent.log 2>&1 &'".format(self.voltha_loc,
+                                          self.service_map['fluentd']['ip'],
+                                          self.controller)
+        ret = os.system(ofagent_start_cmd)
+        if ret != 0:
+            raise Exception('VOLTHA ofagent not started. Failed with return code %d' %ret)
+
+    def kill_service(self, pattern):
+        st, output = getstatusoutput('pgrep -f "{}"'.format(pattern))
+        if st == 0 and output:
+            pids = output.strip().splitlines()
+            for pid in pids:
+                try:
+                    os.kill(int(pid), signal.SIGKILL)
+                except:
+                    pass
+
+    def stop(self):
+        self.kill_service('python voltha/main.py')
+        self.kill_service('python ofagent/main.py')
+        self.kill_service('python chameleon/main.py')
+        service_stop_cmd = 'docker-compose -f {} down'.format(self.compose_file_loc)
+        os.system(service_stop_cmd)
 
 class VolthaCtrl(object):
 
diff --git a/src/test/voltha/volthaTest.json b/src/test/voltha/volthaTest.json
index 8ad1319..d397700 100644
--- a/src/test/voltha/volthaTest.json
+++ b/src/test/voltha/volthaTest.json
@@ -1,5 +1,5 @@
 {
-    "OLT_TYPE" : "tibit_olt",
+    "OLT_TYPE" : "simulated_olt",
     "OLT_MAC"  : "00:0c:e2:31:12:00",
     "VOLTHA_HOST" : "172.17.0.1",
     "VOLTHA_REST_PORT" : 8881
diff --git a/src/test/voltha/volthaTest.py b/src/test/voltha/volthaTest.py
index 526f593..0620e4b 100644
--- a/src/test/voltha/volthaTest.py
+++ b/src/test/voltha/volthaTest.py
@@ -249,7 +249,7 @@
         6  Verify that subscriber should not get ip from dhcp server, ping to gateway.
         """
 
-def test_subscriber_with_voltha_for_dhcp_starvation_positive_scenario(self):
+    def test_subscriber_with_voltha_for_dhcp_starvation_positive_scenario(self):
         """
         Test Method:
         0. Make sure that voltha is up and running on CORD-POD setup.
@@ -856,4 +856,3 @@
         6. Pause the olt device which is detected in voltha.
         7. Verify that subscriber should not get ip from external dhcp server. and other subscriber ping to gateway should failed.
         """
-