add nettest client code and some bugfix 51/54151/2
authorQiang Dai <Qiang.Dai@spirent.com>
Tue, 20 Mar 2018 04:06:49 +0000 (12:06 +0800)
committerQiang Dai <Qiang.Dai@spirent.com>
Tue, 20 Mar 2018 06:12:49 +0000 (14:12 +0800)
1. add nettest client code
2. provide get testcase result file interface
3. delete useless code to avoid produce userdata file
4. modify throughput parameter to shrink test time

Change-Id: I88edccab326381aadb6f7a64a6005e461325055b
Signed-off-by: Qiang Dai <Qiang.Dai@spirent.com>
contrib/nettest/nettest/rest_server.py
contrib/nettest/nettest/rfc2544test.py
contrib/nettest/nettest/stcv_stack.py
contrib/nettest_client/nettest_client.py [new file with mode: 0644]

index ee13c91..3558b9a 100644 (file)
@@ -7,9 +7,10 @@
 # http://www.apache.org/licenses/LICENSE-2.0
 ##############################################################################
 
+import os
 import logging
 
-from flask import Flask, abort, jsonify, request
+from flask import Flask, abort, jsonify, request, send_from_directory
 from flask_cors import CORS
 from flask_restful import Api, Resource, fields
 from flask_restful_swagger import swagger
@@ -23,6 +24,13 @@ api = swagger.docs(Api(app), apiVersion="1.0")
 stcv_master = NetTestMaster()
 
 
+@app.route("/tc_results/<tc_id>", methods=["GET"])
+def download_result_file(tc_id):
+    directory = os.getcwd() + "/tc_results/rfc2544/" + tc_id
+    files = os.listdir(directory)
+    return send_from_directory(directory, files[0], as_attachment=True)
+
+
 @swagger.model
 class StackRequestModel:
     resource_fields = {
index 688b4d1..3764b35 100644 (file)
@@ -200,14 +200,14 @@ class StcRfc2544Test:
 
     default_additional_params = {
         "AcceptableFrameLoss": 0.0,
-        "Duration": 60,
+        "Duration": 30,
         "FrameSizeList": 64,
         "LearningMode": 'AUTO',
         "NumOfTrials": 1,
-        "RateInitial": 99.0,
-        "RateLowerLimit": 99.0,
-        "RateStep": 10.0,
-        "RateUpperLimit": 99.0,
+        "RateInitial": 99.0,
+        "RateLowerLimit": 99.0,
+        "RateStep": 10.0,
+        "RateUpperLimit": 99.0,
         "Resolution": 1.0,
         "SearchMode": 'BINARY',
         "TrafficPattern": 'PAIR'
index 6e69f47..7c1d433 100644 (file)
@@ -20,9 +20,6 @@ from keystoneauth1 import session
 class StcvStack(object):
     STCV_CONFIG_FILE = 'stcv_config_file'
     STCV_HEAT_FILE = './heat_2stcv.yaml'
-    STCV_USER_DATA = '''#cloud-config
-    spirent:
-        ntp: '''
 
     def __init__(self, name, **kwargs):
         self.logger = logging.getLogger(__name__)
@@ -63,12 +60,6 @@ class StcvStack(object):
         self._heat_client = heatclient.Client("1", session=sess)
 
     def _make_parameters(self):
-        user_data = self.STCV_USER_DATA + self.ntp_server_ip
-        file_path = os.getcwd() + '/' + self.STCV_CONFIG_FILE
-        fd = open(file_path, 'w')
-        fd.writelines(user_data)
-        fd.close()
-
         return {
             'public_net_name': self.pub_net_name,
             'stcv_image': self.stcv_image,
diff --git a/contrib/nettest_client/nettest_client.py b/contrib/nettest_client/nettest_client.py
new file mode 100644 (file)
index 0000000..5215fa5
--- /dev/null
@@ -0,0 +1,190 @@
+##############################################################################
+# Copyright (c) 2018 Spirent Communications and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+import os
+import logging
+import requests
+import json
+import time
+
+
+class NettestClient(object):
+
+    def __init__(self, rest_server_ip, port, version):
+        self.logger = logging.getLogger(__name__)
+
+        self.rest_server_ip = rest_server_ip
+        self.port = port
+        self.version = version
+        self.base_url = "http://" + self.rest_server_ip + ":" + str(port) + "/api/" + "v" + self.version + "/"
+        self.headers = {"Content-Type": "application/json"}
+
+    def write_log(self, log):
+        self.logger.info(log)
+        print log
+
+    def create_stack(self, name, stack_type, public_network_name, **kargs):
+        stack_id = None
+
+        try:
+            payload = {
+                "stack_name": name,
+                "stack_type": stack_type,
+                "public_network": public_network_name,
+                "stack_params": {
+                    "stcv_affinity": kargs.get("stcv_affinity"),
+                    "stcv_image": kargs.get("stcv_image"),
+                    "stcv_flavor": kargs.get("stcv_flavor"),
+                    "lab_server_ip": kargs.get("lab_server_ip"),
+                    "license_server_ip": kargs.get("license_server_ip")
+                }
+            }
+
+            stack_url = self.base_url + "stack"
+            response = requests.post(url=stack_url, headers=self.headers, json=payload)
+            if requests.codes.ok != response.status_code:
+                self.write_log("create stack fail, response_content = " + response.content)
+                return None
+            print response.content
+            stack_id = json.loads(response.content)["stack_id"]
+        except Exception as err:
+            self.write_log("create stack fail, error = " + str(err))
+
+        return stack_id
+
+    def destroy_stack(self, stack_id):
+        payload = {"id": stack_id}
+        url = self.base_url + "stack"
+        try:
+            response = requests.delete(url, params=payload)
+            if requests.codes.ok != response.status_code:
+                self.write_log("delete stack fail, err: " + response.content)
+        except Exception as err:
+            self.write_log("delete stack fail, error = " + str(err))
+            return
+
+        self.write_log("delete stack success")
+
+    def run_rfc2544_testcase(self, stack_id, tc_name, metric_type, framesizes):
+        url = self.base_url + "testcase"
+        payload = {
+            "name": tc_name,
+            "stack_id": stack_id,
+            "category": "rfc2544",
+            "params": {
+                "metric": metric_type,
+                "framesizes": framesizes
+            }
+        }
+        try:
+            response = requests.post(url, headers=self.headers, json=payload)
+            if requests.codes.ok != response.status_code:
+                self.write_log("run rfc2544 testcase fail, err = " + response.content)
+                return None
+        except Exception as err:
+            self.write_log("run rfc2544 testcase fail, err = " + str(err))
+            return None
+
+        self.write_log("run rfc2544 testcase success")
+
+        tc_id = json.loads(response.content)["tc_id"]
+
+        return tc_id
+
+    def delete_testcase(self, tc_id):
+        url = self.base_url + "testcase"
+        params = {"tc_id": tc_id}
+        try:
+            response = requests.delete(url, params=params)
+            if requests.codes.ok != response.status_code:
+                self.write_log("delete testcase fail, err = " + response.content)
+        except Exception as err:
+            self.write_log("delete testcase fail, err = " + str(err))
+
+    def write_result(self, result):
+        pass
+
+    def get_tc_result(self, tc_id):
+        ret = False
+        url = self.base_url + "testcase"
+        status_params = {
+            "id": tc_id,
+            "type": "status"
+        }
+        while True:
+            response = requests.get(url, params=status_params)
+            if requests.codes.ok == response.status_code:
+                status = json.loads(response.content)["status"]
+                if status == "running":
+                    time.sleep(2)
+                    continue
+                elif status == "finished":
+                    url = "http://" + self.rest_server_ip + ":" + str(self.port) + "/tc_results/" + tc_id
+                    response = requests.get(url)
+                    if requests.codes.ok == response.status_code:
+                        self.write_log("get tc result success")
+                        with open(os.getcwd() + "/" + tc_id, "w") as fd:
+                            fd.write(response.content)
+                        break
+                        ret = True
+                    else:
+                        self.write_log(response.content)
+                        break
+                else:
+                    self.write_log(response.content)
+                    break
+            else:
+                self.write_log(response.content)
+                break
+
+        return ret
+
+
+if __name__ == "__main__":
+
+    nc = NettestClient(rest_server_ip="127.0.0.1", port=5001, version="1.0")
+
+    stack_params = {
+        "name": 's1',
+        "stack_type": "stcv",
+        "public_network_name": "public",
+        "stcv_affinity": True,
+        "stcv_image": "STCv-4.80.2426",
+        "stcv_flavor": "small.shared",
+        "lab_server_ip": '10.61.67.53',
+        "license_server_ip": '10.140.88.61',
+    }
+
+    stack_id = nc.create_stack(**stack_params)
+    if stack_id is None:
+        print "create stack fail"
+        # exit(1)
+
+    # wait stcv vm into stable status
+    time.sleep(30)
+
+    tc_params = {
+        "stack_id": stack_id,
+        "tc_name": "tc1",
+        "metric_type": "throughput",
+        "framesizes": [64, 128, 256, 512, 1024]
+    }
+    tc_id = nc.run_rfc2544_testcase(**tc_params)
+    if tc_id is None:
+        print "run testcase fail"
+        nc.destroy_stack(stack_id)
+        exit(1)
+
+    result = nc.get_tc_result(tc_id)
+    if result is False:
+        print "get testcase result fail"
+
+    nc.delete_testcase(tc_id)
+
+    nc.destroy_stack(stack_id)