summaryrefslogtreecommitdiffstats
path: root/scripts/automation
diff options
context:
space:
mode:
authorDan Klein <danklein10@gmail.com>2016-01-04 23:31:31 +0200
committerDan Klein <danklein10@gmail.com>2016-01-04 23:31:31 +0200
commit629b54c4c9df9c718d818a004ecf15c2cf6c770a (patch)
tree7dfc3c64c7561032d690ce6188130e80d344054e /scripts/automation
parent3757099103ed1bf56f85ccf5bb861a331287cbbb (diff)
parent857bdcf05a920b99e1cf180c700176b04801da00 (diff)
Merge branch 'master' into dan_stateless
Diffstat (limited to 'scripts/automation')
-rwxr-xr-xscripts/automation/trex_control_plane/client/trex_client.py67
-rw-r--r--scripts/automation/trex_control_plane/client/trex_stateless_sim.py202
-rwxr-xr-xscripts/automation/trex_control_plane/client_utils/external_packages.py41
-rwxr-xr-xscripts/automation/trex_control_plane/client_utils/parsing_opts.py5
-rwxr-xr-xscripts/automation/trex_control_plane/client_utils/yaml_utils.py3
-rwxr-xr-xscripts/automation/trex_control_plane/common/rpc_defaults.yaml17
-rwxr-xr-xscripts/automation/trex_control_plane/common/text_opts.py22
-rwxr-xr-xscripts/automation/trex_control_plane/common/trex_stats.py128
-rwxr-xr-xscripts/automation/trex_control_plane/server/outer_packages.py12
9 files changed, 468 insertions, 29 deletions
diff --git a/scripts/automation/trex_control_plane/client/trex_client.py b/scripts/automation/trex_control_plane/client/trex_client.py
index 5709b7a5..1d94dc06 100755
--- a/scripts/automation/trex_control_plane/client/trex_client.py
+++ b/scripts/automation/trex_control_plane/client/trex_client.py
@@ -294,6 +294,34 @@ class CTRexClient(object):
finally:
self.prompt_verbose_data()
+ def is_idle (self):
+ """
+ Poll for TRex running status, check if TRex is in Idle state.
+
+ :parameters:
+ None
+
+ :return:
+ + **True** if TRex is idle.
+ + **False** if TRex is starting or running.
+
+ :raises:
+ + :exc:`trex_exceptions.TRexIncompleteRunError`, in case one of failed TRex run (unexpected termination).
+ + :exc:`TypeError`, in case JSON stream decoding error.
+ + ProtocolError, in case of error in JSON-RPC protocol.
+
+ """
+ try:
+ if self.get_running_status()['state'] == TRexStatus.Idle:
+ return True
+ return False
+ except TRexException:
+ raise
+ except ProtocolError as err:
+ raise
+ finally:
+ self.prompt_verbose_data()
+
def get_trex_files_path (self):
"""
Fetches the local path in which files are stored when pushed to TRex server from client.
@@ -455,6 +483,41 @@ class CTRexClient(object):
results = self.get_result_obj()
return results
+ def sample_x_seconds (self, sample_time, time_between_samples = 5):
+ """
+ Automatically sets ongoing sampling of TRex data for sample_time seconds, with sampling rate described by time_between_samples.
+ Does not stop the TRex afterwards!
+
+ .. tip:: Useful for changing the device (Router, ASA etc.) configuration after given time.
+
+ :parameters:
+ sample_time : int
+ sample the TRex this number of seconds
+
+ time_between_samples : int
+ determines the time between each sample of the server
+
+ default value : **5**
+
+ :return:
+ the first result object (see :class:`CTRexResult` for further details) of the TRex run after given sample_time.
+
+ :raises:
+ + :exc:`UserWarning`, in case the TRex run ended before sample_time duration
+ + :exc:`trex_exceptions.TRexIncompleteRunError`, in case one of failed TRex run (unexpected termination).
+ + :exc:`TypeError`, in case JSON stream decoding error.
+ + ProtocolError, in case of error in JSON-RPC protocol.
+
+ """
+ # make sure TRex is running. raise exceptions here if any
+ self.wait_until_kickoff_finish()
+ elapsed_time = 0
+ while self.is_running():
+ if elapsed_time >= sample_time:
+ return self.get_result_obj()
+ time.sleep(time_between_samples)
+ elapsed_time += time_between_samples
+ raise UserWarning("TRex has stopped at %s seconds (before expected %s seconds)\nTry increasing test duration or decreasing sample_time" % (elapsed_time, sample_time))
def get_result_obj (self, copy_obj = True):
"""
@@ -1041,11 +1104,11 @@ class CTRexResult(object):
# handle latency data
if self.latency_checked:
latency_pre = "trex-latency"
- self._max_latency = self.get_last_value("{latency}.data".format(latency = latency_pre), ".*max-")#None # TBC
+ self._max_latency = self.get_last_value("{latency}.data".format(latency = latency_pre), "max-")#None # TBC
# support old typo
if self._max_latency is None:
latency_pre = "trex-latecny"
- self._max_latency = self.get_last_value("{latency}.data".format(latency = latency_pre), ".*max-")
+ self._max_latency = self.get_last_value("{latency}.data".format(latency = latency_pre), "max-")
self._avg_latency = self.get_last_value("{latency}.data".format(latency = latency_pre), "avg-")#None # TBC
self._avg_latency = CTRexResult.__avg_all_and_rename_keys(self._avg_latency)
diff --git a/scripts/automation/trex_control_plane/client/trex_stateless_sim.py b/scripts/automation/trex_control_plane/client/trex_stateless_sim.py
new file mode 100644
index 00000000..7655b27c
--- /dev/null
+++ b/scripts/automation/trex_control_plane/client/trex_stateless_sim.py
@@ -0,0 +1,202 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Itay Marom
+Cisco Systems, Inc.
+
+Copyright (c) 2015-2015 Cisco Systems, Inc.
+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.
+"""
+
+try:
+ # support import for Python 2
+ import outer_packages
+except ImportError:
+ # support import for Python 3
+ import client.outer_packages
+
+from client_utils.jsonrpc_client import JsonRpcClient, BatchMessage
+from client_utils.packet_builder import CTRexPktBuilder
+import json
+
+from common.trex_streams import *
+
+import argparse
+import tempfile
+import subprocess
+import os
+
+
+
+class SimRun(object):
+ def __init__ (self, yaml_file, dp_core_count, core_index, packet_limit, output_filename, is_valgrind, is_gdb):
+
+ self.yaml_file = yaml_file
+ self.output_filename = output_filename
+ self.dp_core_count = dp_core_count
+ self.core_index = core_index
+ self.packet_limit = packet_limit
+ self.is_valgrind = is_valgrind
+ self.is_gdb = is_gdb
+
+ # dummies
+ self.handler = 0
+ self.port_id = 0
+ self.mul = {"op": "abs",
+ "type": "raw",
+ "value": 1}
+
+ self.duration = -1
+
+ def load_yaml_file (self):
+ streams_db = CStreamsDB()
+ stream_list = streams_db.load_yaml_file(self.yaml_file)
+
+ streams_json = []
+ for stream in stream_list.compiled:
+ stream_json = {"id":1,
+ "jsonrpc": "2.0",
+ "method": "add_stream",
+ "params": {"handler": self.handler,
+ "port_id": self.port_id,
+ "stream_id": stream.stream_id,
+ "stream": stream.stream}
+ }
+
+ streams_json.append(stream_json)
+
+ return streams_json
+
+
+ def generate_start_cmd (self):
+ return {"id":1,
+ "jsonrpc": "2.0",
+ "method": "start_traffic",
+ "params": {"handler": self.handler,
+ "port_id": self.port_id,
+ "mul": self.mul,
+ "duration": self.duration}
+ }
+
+
+ def run (self):
+
+ # load the streams
+ cmds_json = (self.load_yaml_file())
+ cmds_json.append(self.generate_start_cmd())
+
+ f = tempfile.NamedTemporaryFile(delete = False)
+ f.write(json.dumps(cmds_json))
+ f.close()
+
+ try:
+ cmd = ['bp-sim-64-debug', '--sl', '--cores', str(self.dp_core_count), '--core_index', str(self.core_index), '-f', f.name, '-o', self.output_filename]
+ if self.is_valgrind:
+ cmd = ['valgrind', '--leak-check=full'] + cmd
+ elif self.is_gdb:
+ cmd = ['gdb', '--args'] + cmd
+
+ subprocess.call(cmd)
+
+ finally:
+ os.unlink(f.name)
+
+
+def is_valid_file(filename):
+ if not os.path.isfile(filename):
+ raise argparse.ArgumentTypeError("The file '%s' does not exist" % filename)
+
+ return filename
+
+
+def unsigned_int (x):
+ x = int(x)
+ if x <= 0:
+ raise argparse.ArgumentTypeError("argument must be >= 1")
+
+ return x
+
+def setParserOptions():
+ parser = argparse.ArgumentParser(prog="stl_sim.py")
+
+ parser.add_argument("input_file",
+ help = "input file in YAML or Python format",
+ type = is_valid_file)
+
+ parser.add_argument("output_file",
+ help = "output file in ERF format")
+
+
+ parser.add_argument("-c", "--cores",
+ help = "DP core count [default is 1]",
+ default = 1,
+ type = int,
+ choices = xrange(1, 9))
+
+ parser.add_argument("-n", "--core_index",
+ help = "DP core index to examine [default is 0]",
+ default = 0,
+ type = int)
+
+ parser.add_argument("-j", "--join",
+ help = "run and join output from 0..core_count [default is False]",
+ default = False,
+ type = bool)
+
+ parser.add_argument("-l", "--limit",
+ help = "limit test total packet count [default is 5000]",
+ default = 5000,
+ type = unsigned_int)
+
+
+ group = parser.add_mutually_exclusive_group()
+
+ group.add_argument("-x", "--valgrind",
+ help = "run under valgrind [default is False]",
+ action = "store_true",
+ default = False)
+
+ group.add_argument("-g", "--gdb",
+ help = "run under GDB [default is False]",
+ action = "store_true",
+ default = False)
+
+ return parser
+
+
+def validate_args (parser, options):
+ if options.core_index < 0 or options.core_index >= options.cores:
+ parser.error("DP core index valid range is 0 to {0}".format(options.cores - 1))
+
+
+
+def main ():
+ parser = setParserOptions()
+ options = parser.parse_args()
+
+ validate_args(parser, options)
+
+ r = SimRun(options.input_file,
+ options.cores,
+ options.core_index,
+ options.limit,
+ options.output_file,
+ options.valgrind,
+ options.gdb)
+
+ r.run()
+
+
+if __name__ == '__main__':
+ main()
+
+
diff --git a/scripts/automation/trex_control_plane/client_utils/external_packages.py b/scripts/automation/trex_control_plane/client_utils/external_packages.py
index 3c6eb449..3982a1b2 100755
--- a/scripts/automation/trex_control_plane/client_utils/external_packages.py
+++ b/scripts/automation/trex_control_plane/client_utils/external_packages.py
@@ -7,15 +7,16 @@ CURRENT_PATH = os.path.dirname(os.path.realpath(__file__))
ROOT_PATH = os.path.abspath(os.path.join(CURRENT_PATH, os.pardir)) # path to trex_control_plane directory
PATH_TO_PYTHON_LIB = os.path.abspath(os.path.join(ROOT_PATH, os.pardir, os.pardir, 'external_libs'))
-CLIENT_UTILS_MODULES = ['zmq',
- 'dpkt-1.8.6',
+CLIENT_UTILS_MODULES = ['dpkt-1.8.6',
'PyYAML-3.01/lib',
'texttable-0.8.4'
]
def import_client_utils_modules():
+
# must be in a higher priority
sys.path.insert(0, PATH_TO_PYTHON_LIB)
+
sys.path.append(ROOT_PATH)
import_module_list(CLIENT_UTILS_MODULES)
@@ -27,5 +28,41 @@ def import_module_list(modules_list):
fix_path = os.path.normcase(full_path)
sys.path.insert(1, full_path)
+
+ import_platform_dirs()
+
+
+
+def import_platform_dirs ():
+ # handle platform dirs
+
+ # try fedora 18 first and then cel5.9
+ # we are using the ZMQ module to determine the right platform
+
+ full_path = os.path.join(PATH_TO_PYTHON_LIB, 'platform/fedora18')
+ fix_path = os.path.normcase(full_path)
+ sys.path.insert(0, full_path)
+ try:
+ # try to import and delete it from the namespace
+ import zmq
+ del zmq
+ return
+ except:
+ pass
+
+ full_path = os.path.join(PATH_TO_PYTHON_LIB, 'platform/cel59')
+ fix_path = os.path.normcase(full_path)
+ sys.path.insert(0, full_path)
+ try:
+ # try to import and delete it from the namespace
+ import zmq
+ del zmq
+ return
+
+ except:
+ raise Exception("unable to determine platform type for ZMQ import")
+
+
+
import_client_utils_modules()
diff --git a/scripts/automation/trex_control_plane/client_utils/parsing_opts.py b/scripts/automation/trex_control_plane/client_utils/parsing_opts.py
index 6f9b4c6d..5cb06604 100755
--- a/scripts/automation/trex_control_plane/client_utils/parsing_opts.py
+++ b/scripts/automation/trex_control_plane/client_utils/parsing_opts.py
@@ -70,7 +70,10 @@ def match_multiplier_common(val, strict_abs = True):
op = None
else:
match = re.match("^(\d+(\.\d+)?)(bps|kbps|mbps|gbps|pps|kpps|mpps|%?)([\+\-])?$", val)
- op = match.group(4)
+ if match:
+ op = match.group(4)
+ else:
+ op = None
result = {}
diff --git a/scripts/automation/trex_control_plane/client_utils/yaml_utils.py b/scripts/automation/trex_control_plane/client_utils/yaml_utils.py
index 60630a04..825d6fc9 100755
--- a/scripts/automation/trex_control_plane/client_utils/yaml_utils.py
+++ b/scripts/automation/trex_control_plane/client_utils/yaml_utils.py
@@ -14,7 +14,8 @@ 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.
"""
-
+import traceback
+import sys
import external_packages
import yaml
diff --git a/scripts/automation/trex_control_plane/common/rpc_defaults.yaml b/scripts/automation/trex_control_plane/common/rpc_defaults.yaml
index 32631609..9325a0e4 100755
--- a/scripts/automation/trex_control_plane/common/rpc_defaults.yaml
+++ b/scripts/automation/trex_control_plane/common/rpc_defaults.yaml
@@ -50,9 +50,7 @@ stream:
mode:
type: object
vm:
- type: array
- has_default: YES
- default: [] # no ranging instructions
+ type: object
rx_stats:
type: object
@@ -112,4 +110,15 @@ rx_stats:
latency_enabled:
type: boolean
has_default: YES
- default: False \ No newline at end of file
+ default: False
+
+vm:
+ instructions:
+ type: array
+ has_default: YES
+ default: []
+ split_by_var:
+ type: string
+ has_default: YES
+ default: ""
+
diff --git a/scripts/automation/trex_control_plane/common/text_opts.py b/scripts/automation/trex_control_plane/common/text_opts.py
index 5a86149c..29fbd69b 100755
--- a/scripts/automation/trex_control_plane/common/text_opts.py
+++ b/scripts/automation/trex_control_plane/common/text_opts.py
@@ -94,9 +94,16 @@ def underline(text):
def text_attribute(text, attribute):
- return "{start}{txt}{stop}".format(start=TEXT_CODES[attribute]['start'],
- txt=text,
- stop=TEXT_CODES[attribute]['end'])
+ if isinstance(text, str):
+ return "{start}{txt}{stop}".format(start=TEXT_CODES[attribute]['start'],
+ txt=text,
+ stop=TEXT_CODES[attribute]['end'])
+ elif isinstance(text, unicode):
+ return u"{start}{txt}{stop}".format(start=TEXT_CODES[attribute]['start'],
+ txt=text,
+ stop=TEXT_CODES[attribute]['end'])
+ else:
+ raise Exception("not a string")
FUNC_DICT = {'blue': blue,
@@ -117,6 +124,15 @@ def format_text(text, *args):
return_string = func(return_string)
return return_string
+def format_threshold (value, red_zone, green_zone):
+ if value >= red_zone[0] and value <= red_zone[1]:
+ return format_text("{0}".format(value), 'red')
+
+ if value >= green_zone[0] and value <= green_zone[1]:
+ return format_text("{0}".format(value), 'green')
+
+ return "{0}".format(value)
+
# pretty print for JSON
def pretty_json (json_str, use_colors = True):
pretty_str = json.dumps(json.loads(json_str), indent = 4, separators=(',', ': '), sort_keys = True)
diff --git a/scripts/automation/trex_control_plane/common/trex_stats.py b/scripts/automation/trex_control_plane/common/trex_stats.py
index d77d3558..4c6173c4 100755
--- a/scripts/automation/trex_control_plane/common/trex_stats.py
+++ b/scripts/automation/trex_control_plane/common/trex_stats.py
@@ -1,12 +1,13 @@
#!/router/bin/python
-from collections import namedtuple, OrderedDict
+from collections import namedtuple, OrderedDict, deque
from client_utils import text_tables
-from common.text_opts import format_text
+from common.text_opts import format_text, format_threshold
from client.trex_async_client import CTRexAsyncStats
import copy
import datetime
import time
import re
+import math
GLOBAL_STATS = 'g'
PORT_STATS = 'p'
@@ -16,6 +17,44 @@ COMPACT = {GLOBAL_STATS, PORT_STATS}
ExportableStats = namedtuple('ExportableStats', ['raw_data', 'text_table'])
+# use to calculate diffs relative to the previous values
+# for example, BW
+def calculate_diff (samples):
+ total = 0.0
+
+ weight_step = 1.0 / sum(xrange(0, len(samples)))
+ weight = weight_step
+
+ for i in xrange(0, len(samples) - 1):
+ current = samples[i] if samples[i] > 0 else 1
+ next = samples[i + 1] if samples[i + 1] > 0 else 1
+
+ s = 100 * ((float(next) / current) - 1.0)
+
+ # block change by 100%
+ total += (min(s, 100) * weight)
+ weight += weight_step
+
+ return total
+
+
+# calculate by absolute values and not relatives (useful for CPU usage in % and etc.)
+def calculate_diff_raw (samples):
+ total = 0.0
+
+ weight_step = 1.0 / sum(xrange(0, len(samples)))
+ weight = weight_step
+
+ for i in xrange(0, len(samples) - 1):
+ current = samples[i]
+ next = samples[i + 1]
+
+ total += ( (next - current) * weight )
+ weight += weight_step
+
+ return total
+
+
class CTRexInfoGenerator(object):
"""
@@ -202,7 +241,7 @@ class CTRexStats(object):
self.reference_stats = None
self.latest_stats = {}
self.last_update_ts = time.time()
-
+ self.history = deque(maxlen = 10)
def __getitem__(self, item):
# override this to allow quick and clean access to fields
@@ -254,6 +293,7 @@ class CTRexStats(object):
def update(self, snapshot):
# update
self.latest_stats = snapshot
+ self.history.append(snapshot)
diff_time = time.time() - self.last_update_ts
@@ -286,6 +326,54 @@ class CTRexStats(object):
else:
return self.format_num(self.latest_stats[field] - self.reference_stats[field], suffix)
+ # get trend for a field
+ def get_trend (self, field, use_raw = False):
+ if not field in self.latest_stats:
+ return 0
+
+ if len(self.history) < 5:
+ return 0
+
+ field_samples = [sample[field] for sample in self.history]
+
+ if use_raw:
+ return calculate_diff_raw(field_samples)
+ else:
+ return calculate_diff(field_samples)
+
+
+ def get_trend_gui (self, field, show_value = True, use_raw = False, up_color = 'red', down_color = 'green'):
+ v = self.get_trend(field, use_raw)
+
+ value = abs(v)
+ arrow = u'\u25b2' if v > 0 else u'\u25bc'
+ color = up_color if v > 0 else down_color
+
+ # change in 1% is not meaningful
+ if value < 1:
+ return ""
+
+ elif value > 5:
+
+ if show_value:
+ return format_text(u"{0}{0}{0} {1:.2f}%".format(arrow,v), color)
+ else:
+ return format_text(u"{0}{0}{0}".format(arrow), color)
+
+ elif value > 2:
+
+ if show_value:
+ return format_text(u"{0}{0} {1:.2f}%".format(arrow,v), color)
+ else:
+ return format_text(u"{0}{0}".format(arrow), color)
+
+ else:
+ if show_value:
+ return format_text(u"{0} {1:.2f}%".format(arrow,v), color)
+ else:
+ return format_text(u"{0}".format(arrow), color)
+
+
class CGlobalStats(CTRexStats):
@@ -300,11 +388,19 @@ class CGlobalStats(CTRexStats):
port=self.connection_info.get("sync_port"))),
("version", "{ver}, UUID: {uuid}".format(ver=self.server_version.get("version", "N/A"),
uuid="N/A")),
- ("cpu_util", "{0}%".format(self.get("m_cpu_util"))),
- ("total_tx", self.get("m_tx_bps", format=True, suffix="b/sec")),
- ("total_rx", self.get("m_rx_bps", format=True, suffix="b/sec")),
- ("total_pps", self.format_num(self.get("m_tx_pps") + self.get("m_rx_pps"),
- suffix="pkt/sec")),
+
+ ("cpu_util", u"{0}% {1}".format( format_threshold(self.get("m_cpu_util"), [85, 100], [0, 85]),
+ self.get_trend_gui("m_cpu_util", use_raw = True))),
+
+ ("total_tx", u"{0} {1}".format( self.get("m_tx_bps", format=True, suffix="b/sec"),
+ self.get_trend_gui("m_tx_bps"))),
+
+ ("total_rx", u"{0} {1}".format( self.get("m_rx_bps", format=True, suffix="b/sec"),
+ self.get_trend_gui("m_rx_bps"))),
+
+ ("total_pps", u"{0} {1}".format( self.get("m_tx_pps", format=True, suffix="pkt/sec"),
+ self.get_trend_gui("m_tx_pps"))),
+
("total_streams", sum([len(port_obj.streams)
for _, port_obj in self._ports_dict.iteritems()])),
("active_ports", sum([port_obj.is_active()
@@ -335,11 +431,19 @@ class CPortStats(CTRexStats):
"rx-pkts": self.get_rel("ipackets", format = True, suffix = "pkts"),
"---": "",
- "Tx bps": self.get("m_total_tx_bps", format = True, suffix = "bps"),
- "Rx bps": self.get("m_total_rx_bps", format = True, suffix = "bps"),
+ "Tx bps": u"{0} {1}".format(self.get_trend_gui("m_total_tx_bps", show_value = False, up_color = None, down_color = None),
+ self.get("m_total_tx_bps", format = True, suffix = "bps")),
+
+ "Rx bps": u"{0} {1}".format(self.get_trend_gui("m_total_rx_bps", show_value = False, up_color = None, down_color = None),
+ self.get("m_total_rx_bps", format = True, suffix = "bps")),
+
"----": "",
- "Tx pps": self.get("m_total_tx_pps", format = True, suffix = "pps"),
- "Rx pps": self.get("m_total_rx_pps", format = True, suffix = "pps"),
+ "Tx pps": u"{0} {1}".format(self.get_trend_gui("m_total_tx_pps", show_value = False, up_color = None, down_color = None),
+ self.get("m_total_tx_pps", format = True, suffix = "pps")),
+
+ "Rx pps": u"{0} {1}".format(self.get_trend_gui("m_total_rx_pps", show_value = False, up_color = None, down_color = None),
+ self.get("m_total_rx_pps", format = True, suffix = "pps")),
+
}
diff --git a/scripts/automation/trex_control_plane/server/outer_packages.py b/scripts/automation/trex_control_plane/server/outer_packages.py
index 2234c734..3d4f039a 100755
--- a/scripts/automation/trex_control_plane/server/outer_packages.py
+++ b/scripts/automation/trex_control_plane/server/outer_packages.py
@@ -3,13 +3,14 @@
import sys
import os
-CURRENT_PATH = os.path.dirname(os.path.realpath(__file__))
-ROOT_PATH = os.path.abspath(os.path.join(CURRENT_PATH, os.pardir)) # path to trex_control_plane directory
-PATH_TO_PYTHON_LIB = os.path.abspath(os.path.join(ROOT_PATH, os.pardir, os.pardir, 'external_libs'))
+CURRENT_PATH = os.path.dirname(os.path.realpath(__file__))
+ROOT_PATH = os.path.abspath(os.path.join(CURRENT_PATH, os.pardir)) # path to trex_control_plane directory
+PATH_TO_PYTHON_LIB = os.path.abspath(os.path.join(ROOT_PATH, os.pardir, os.pardir, 'external_libs'))
+PATH_TO_PLATFORM_LIB = os.path.abspath(os.path.join(PATH_TO_PYTHON_LIB, 'platform/fedora18'))
SERVER_MODULES = ['enum34-1.0.4',
- 'jsonrpclib-pelix-0.2.5',
'zmq',
+ 'jsonrpclib-pelix-0.2.5',
'python-daemon-2.0.5',
'lockfile-0.10.2',
'termstyle'
@@ -19,6 +20,7 @@ SERVER_MODULES = ['enum34-1.0.4',
def import_server_modules():
# must be in a higher priority
sys.path.insert(0, PATH_TO_PYTHON_LIB)
+ sys.path.insert(0, PATH_TO_PLATFORM_LIB)
sys.path.append(ROOT_PATH)
import_module_list(SERVER_MODULES)
@@ -30,4 +32,6 @@ def import_module_list(modules_list):
fix_path = os.path.normcase(full_path)
sys.path.insert(1, full_path)
+
import_server_modules()
+