A R Karthick | 23c9607 | 2017-08-21 20:34:21 -0700 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | |
| 3 | # Copyright 2017-present Open Networking Foundation |
| 4 | # |
| 5 | # Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | # you may not use this file except in compliance with the License. |
| 7 | # You may obtain a copy of the License at |
| 8 | # |
| 9 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | # |
| 11 | # Unless required by applicable law or agreed to in writing, software |
| 12 | # distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | # See the License for the specific language governing permissions and |
| 15 | # limitations under the License. |
| 16 | from argparse import ArgumentParser |
| 17 | import os |
| 18 | import sys |
| 19 | utils_dir = os.path.join( os.path.dirname(os.path.realpath(__file__)), '../utils') |
| 20 | cli_dir = os.path.join( os.path.dirname(os.path.realpath(__file__)), '../cli') |
| 21 | sys.path.append(utils_dir) |
| 22 | sys.path.append(cli_dir) |
| 23 | sys.path.insert(1, '/usr/local/lib/python2.7/dist-packages') |
| 24 | from CordTestUtils import getstatusoutput |
| 25 | import time |
| 26 | import requests |
| 27 | import httplib |
| 28 | import json |
| 29 | import signal |
| 30 | |
| 31 | class CordTesterWebClient(object): |
| 32 | |
| 33 | def __init__(self, host = 'localhost', port = 5000): |
| 34 | self.host = host |
| 35 | self.port = port |
| 36 | self.rest = 'http://{}:{}'.format(self.host, self.port) |
| 37 | |
| 38 | def get_config(self, test_case): |
| 39 | rest_uri = '{}/get'.format(self.rest) |
| 40 | config = { 'test_case' : test_case } |
| 41 | resp = requests.get(rest_uri, data = json.dumps(config)) |
| 42 | if resp.ok and resp.status_code == 200: |
| 43 | config = resp.json() |
| 44 | return config |
| 45 | return None |
| 46 | |
| 47 | def set_config(self, test_case, test_config): |
| 48 | rest_uri = '{}/update'.format(self.rest) |
| 49 | config = { 'test_case' : test_case, 'config' : test_config } |
| 50 | resp = requests.post(rest_uri, data = json.dumps(config)) |
| 51 | return resp.ok, resp.status_code |
| 52 | |
| 53 | def restore_config(self, test_case): |
| 54 | rest_uri = '{}/restore'.format(self.rest) |
| 55 | config = { 'test_case' : test_case } |
| 56 | resp = requests.post(rest_uri, data = json.dumps(config)) |
| 57 | return resp.ok, resp.status_code |
| 58 | |
| 59 | def start(self, manifest = 'manifest.json'): |
| 60 | rest_uri = '{}/start'.format(self.rest) |
| 61 | config = { 'manifest' : manifest } |
| 62 | resp = requests.post(rest_uri, data = json.dumps(config)) |
| 63 | return resp.ok, resp.status_code |
| 64 | |
| 65 | def cleanup(self, manifest = 'manifest.json'): |
| 66 | rest_uri = '{}/cleanup'.format(self.rest) |
| 67 | config = { 'manifest' : manifest } |
| 68 | resp = requests.post(rest_uri, data = json.dumps(config)) |
| 69 | return resp.ok, resp.status_code |
| 70 | |
| 71 | def test(self, test, manifest = 'manifest.json', test_config = None): |
| 72 | rest_uri = '{}/test'.format(self.rest) |
| 73 | config = { 'manifest' : manifest, 'test' : test } |
| 74 | if test_config: |
| 75 | config['config'] = test_config |
| 76 | resp = requests.post(rest_uri, data = json.dumps(config)) |
| 77 | return resp.ok, resp.status_code |
| 78 | |
| 79 | class Tester(CordTesterWebClient): |
| 80 | |
| 81 | def __init__(self, host = 'localhost', port = 5000): |
| 82 | super(Tester, self).__init__(host = host, port = port) |
| 83 | |
| 84 | def execute(self, test_case, manifest = 'manifest.json', test_config = None): |
| 85 | print('Executing test %s' %test_case) |
| 86 | _, status = self.start(manifest = manifest) |
| 87 | assert status == httplib.OK, 'Test setup failed with status code %d' %status |
| 88 | _, status = self.test(test_case, manifest = manifest, test_config = test_config) |
| 89 | assert status == httplib.OK, 'Test run for test %s failed with status %d' %(test_case, status) |
| 90 | _, status = self.cleanup(manifest = manifest) |
| 91 | assert status == httplib.OK, 'Test cleanup failed with status %d' %status |
| 92 | print('Test executed successfully') |
| 93 | |
| 94 | |
| 95 | class CordTesterWeb(object): |
| 96 | |
| 97 | def __init__(self, args, start_in = 3): |
| 98 | self.args = args |
| 99 | self.tester = Tester() |
| 100 | self.start_in = start_in |
| 101 | |
| 102 | def run(self): |
| 103 | manifest = self.args.manifest |
| 104 | olt_type = self.args.olt_type |
| 105 | test_type = self.args.test_type |
A R Karthick | 18d0fb6 | 2017-09-01 18:49:07 -0700 | [diff] [blame] | 106 | disable_teardown = self.args.disable_teardown |
| 107 | test_mode = self.args.test_mode |
| 108 | disable_cleanup = self.args.disable_cleanup |
| 109 | if test_mode is True: |
| 110 | disable_cleanup = True |
A R Karthick | 23c9607 | 2017-08-21 20:34:21 -0700 | [diff] [blame] | 111 | test_config = { 'VOLTHA_HOST' : self.args.voltha_host, |
| 112 | 'VOLTHA_OLT_TYPE' : self.args.olt_type, |
A R Karthick | 18d0fb6 | 2017-09-01 18:49:07 -0700 | [diff] [blame] | 113 | 'VOLTHA_TEARDOWN' : not disable_teardown, |
A R Karthick | 23c9607 | 2017-08-21 20:34:21 -0700 | [diff] [blame] | 114 | } |
| 115 | if olt_type.startswith('tibit'): |
| 116 | test_config['VOLTHA_OLT_MAC'] = self.args.olt_arg |
| 117 | elif olt_type.startswith('maple'): |
| 118 | test_config['VOLTHA_OLT_IP'] = self.args.olt_arg |
| 119 | elif olt_type.startswith('ponsim'): |
| 120 | test_config['VOLTHA_PONSIM_HOST'] = self.args.olt_arg |
| 121 | else: |
| 122 | print('Unsupported OLT type %s' %olt_type) |
| 123 | return 127 |
| 124 | |
| 125 | if self.start_in: |
| 126 | time.sleep(self.start_in) |
| 127 | |
A R Karthick | 18d0fb6 | 2017-09-01 18:49:07 -0700 | [diff] [blame] | 128 | if test_mode is False: |
| 129 | _, status = self.tester.start(manifest = manifest) |
| 130 | assert status == httplib.OK, 'Test setup failed with status %d' %status |
A R Karthick | 23c9607 | 2017-08-21 20:34:21 -0700 | [diff] [blame] | 131 | |
| 132 | for test in test_type.split(','): |
| 133 | print('Running test case %s' %(test)) |
| 134 | _, status = self.tester.test(test, manifest = manifest, test_config = test_config) |
| 135 | if status != httplib.OK: |
| 136 | print('Test case %s failed with status code %d' %(test, status)) |
| 137 | |
A R Karthick | 18d0fb6 | 2017-09-01 18:49:07 -0700 | [diff] [blame] | 138 | if disable_cleanup is False: |
| 139 | print('Cleaning up the test') |
| 140 | self.tester.cleanup(manifest = manifest) |
A R Karthick | 23c9607 | 2017-08-21 20:34:21 -0700 | [diff] [blame] | 141 | return 0 if status == httplib.OK else 127 |
| 142 | |
| 143 | class CordTesterWebServer(object): |
| 144 | |
| 145 | server_path = os.path.dirname(os.path.realpath(__file__)) |
| 146 | server = 'webserver-run.py' |
| 147 | pattern = 'pgrep -f "python ./{}"'.format(server) |
| 148 | |
| 149 | def running(self): |
| 150 | st, _ = getstatusoutput(self.pattern) |
| 151 | return True if st == 0 else False |
| 152 | |
| 153 | def kill(self): |
| 154 | st, output = getstatusoutput(self.pattern) |
| 155 | if st == 0 and output: |
| 156 | pids = output.strip().splitlines() |
| 157 | for pid in pids: |
| 158 | try: |
| 159 | os.kill(int(pid), signal.SIGKILL) |
| 160 | except: |
| 161 | pass |
| 162 | |
| 163 | def start(self): |
| 164 | if self.running() is False: |
| 165 | print('Starting CordTester Web Server') |
| 166 | cmd = 'cd {} && python ./{} &'.format(self.server_path, self.server) |
| 167 | os.system(cmd) |
| 168 | |
| 169 | def run_test(args): |
| 170 | testWebServer = CordTesterWebServer() |
| 171 | testWebServer.start() |
| 172 | testWeb = CordTesterWeb(args, start_in = 3) |
| 173 | status = testWeb.run() |
| 174 | testWebServer.kill() |
| 175 | return status |
| 176 | |
| 177 | if __name__ == '__main__': |
Chetan Gaonker | d01ea13 | 2017-10-04 17:20:20 +0000 | [diff] [blame] | 178 | parser = ArgumentParser(description = 'VOLTHA tester') |
A R Karthick | 23c9607 | 2017-08-21 20:34:21 -0700 | [diff] [blame] | 179 | parser.add_argument('-test-type', '--test-type', default = 'tls:eap_auth_exchange.test_eap_tls', help = 'Test type to run') |
| 180 | parser.add_argument('-manifest', '--manifest', default='manifest-voltha.json', help = 'Manifest file to use') |
| 181 | parser.add_argument('-voltha-host', '--voltha-host', default='172.17.0.1', help = 'VOLTHA host ip') |
| 182 | parser.add_argument('-olt-type', '--olt-type', default = 'ponsim_olt', help = 'OLT type') |
| 183 | parser.add_argument('-olt-arg', '--olt-arg', default = '172.17.0.1', help = 'OLT type argument') |
A R Karthick | 18d0fb6 | 2017-09-01 18:49:07 -0700 | [diff] [blame] | 184 | parser.add_argument('-disable-teardown', '--disable-teardown', action='store_true', help = 'Disable VOLTHA teardown') |
| 185 | parser.add_argument('-disable-cleanup', '--disable-cleanup', action='store_true', help = 'Dont cleanup cord-tester') |
| 186 | parser.add_argument('-test-mode', '--test-mode', action='store_true', |
| 187 | help = 'Directly run the cord-tester run-test phase without setup and cleanup') |
| 188 | |
A R Karthick | 23c9607 | 2017-08-21 20:34:21 -0700 | [diff] [blame] | 189 | parser.set_defaults(func = run_test) |
| 190 | args = parser.parse_args() |
| 191 | res = args.func(args) |
| 192 | sys.exit(res) |