Пример #1
0
    def __init__(self, nrange):

        """Construct a range from a JSON NumericRange."""

        # TODO: Would be nice if this class could treat missing
        # lower/upper as -/+ infinity.

        # TODO: Figure out why this can't just point to a NumericRange

        valid, message = pscheduler.json_validate(nrange, {
            "type": "object",
            "properties": {
                "lower": { "$ref": "#/pScheduler/Numeric" },
                "upper": { "$ref": "#/pScheduler/Numeric" }
            },
            "additionalProperties": False,
            "required": [ "lower", "upper" ]
        })

        if not valid:
            raise ValueError("Invalid numeric range: %s" % message)

        lower = nrange['lower']
        if type(lower) in [ str, unicode ]:
            self.lower = pscheduler.si_as_number(lower)
        else:
            self.lower = lower
        self.lower_str = str(lower)

        upper = nrange['upper']
        if type(upper) in [ str, unicode ]:
            self.upper = pscheduler.si_as_number(upper)
        else:
            self.upper = upper
        self.upper_str = str(upper)
Пример #2
0
    def __init__(self, nrange):
        """Construct a range from a JSON NumericRange."""

        # TODO: Would be nice if this class could treat missing
        # lower/upper as -/+ infinity.

        # TODO: Figure out why this can't just point to a NumericRange

        valid, message = pscheduler.json_validate(nrange, {
            "type": "object",
            "properties": {
                "lower": {"$ref": "#/pScheduler/Numeric"},
                "upper": {"$ref": "#/pScheduler/Numeric"}
            },
            "additionalProperties": False,
            "required": ["lower", "upper"]
        })

        if not valid:
            raise ValueError("Invalid numeric range: %s" % message)

        lower = nrange['lower']
        if type(lower) in [str, unicode]:
            self.lower = pscheduler.si_as_number(lower)
        else:
            self.lower = lower
        self.lower_str = str(lower)

        upper = nrange['upper']
        if type(upper) in [str, unicode]:
            self.upper = pscheduler.si_as_number(upper)
        else:
            self.upper = upper
        self.upper_str = str(upper)
Пример #3
0
    def __contains__(self, number):
        """See if the range contains the specified number, which can be any Numeric."""

        if type(number) == float:
            test_value = number
        else:
            test_value = pscheduler.si_as_number(number)

        return self.lower <= test_value <= self.upper
Пример #4
0
    def __contains__(self, number):

        """See if the range contains the specified number, which can be any Numeric."""

        if type(number) == float:
            test_value = number
        else:
            test_value = pscheduler.si_as_number(number)

        return self.lower <= test_value <= self.upper
Пример #5
0
def parse_output(lines):
    results = {}
    results['succeeded'] = True

    seen_header = False
    streams = {}

    dest_ip = None
    dest_port = None
    src_ip = None
    src_port = None

    for line in lines:

        # ignore bogus sessions
        if re.match('\(nan%\)', line):
            results["succeeded"] = False
            results["error"] = "Found NaN result"
            break

        if re.match('read failed: Connection refused', line):
            results["succeeded"] = False
            results["error"] = "Connection refused"
            break

        test = re.match(
            'local ([^ ]+) port (\d+) connected with ([^ ]+) port (\d+)', line)
        if test:
            dest_ip = test.group(1)
            dest_port = test.group(2)
            src_ip = test.group(3)
            src_port = test.group(4)

        # Example lines
        # TCP window size:  244 KByte (WARNING: requested 64.0 MByte)
        # TCP window size: 19800 Byte (default)
        test = re.match(
            'TCP window size:\s+(\d+(\.\d+)?) (\S)?Byte(.*\(WARNING:\s+requested\s+(\d+(\.\d+)?) (\S)?Byte)?',
            line)
        if test:
            window_size = test.group(1)
            window_si = test.group(3)

            request_size = test.group(5)
            request_si = test.group(7)

            if window_si:
                window_size = pscheduler.si_as_number("%s%s" %
                                                      (window_size, window_si))

            if request_size:
                if request_si:
                    request_size = pscheduler.si_as_number(
                        "%s%s" % (request_size, request_si))
                results["requested-tcp-window-size"] = int(request_size)

            results["tcp-window-size"] = int(window_size)

        # Example line
        # [  3] MSS size 1448 bytes (MTU 1500 bytes, ethernet)
        test = re.match('.*MSS size (\d+) bytes \(MTU (\d+) bytes', line)
        if test:
            results['mss'] = int(test.group(1))
            results['mtu'] = int(test.group(2))

        stream_id = None
        interval_start = None
        throughput_bytes = None
        si_bytes = None
        throughput_bits = None
        si_bits = None
        jitter = None
        lost = None
        sent = None

        # Example line
        # [  3] 16.0-17.0 sec  37355520 Bytes  298844160 bits/sec
        test = re.match(
            '\[\s*(\d+|SUM)\s*\]\s+([0-9\.]+)\s*\-\s*([0-9\.]+)\s+sec\s+(\d+(\.\d+)?)\s+(P|T|G|M|K)?Bytes\s+(\d+(\.\d+)?)\s+(P|T|G|M|K)?bits\/sec(\s+([0-9\.]+)\s+ms\s+(\d+)\/\s*(\d+)\s+)?',
            line)
        if test:
            stream_id = test.group(1)
            interval_start = float(test.group(2))
            interval_end = float(test.group(3))
            throughput_bytes = float(test.group(4))
            si_bytes = test.group(6)
            throughput_bits = float(test.group(7))
            si_bits = test.group(9)

            # these may or may not be present depending on versions
            jitter = test.group(11)
            lost = test.group(12)
            send = test.group(13)

            # If the output was in say GBytes convert back to regular Bytes for ease
            # of things later
            if si_bytes:
                throughput_bytes = pscheduler.si_as_number(
                    "%s%s" % (throughput_bytes, si_bytes))
            if si_bits:
                throughput_bits = pscheduler.si_as_number(
                    "%s%s" % (throughput_bits, si_bits))

        # if we found a matching line, we can add this info to our streams
        if stream_id:

            key = "%s-%s" % (interval_start, interval_end)

            # TODO: This would appear to not create a summary when the
            # duration is very short.

            # there has to be a better way than this...
            if interval_end - interval_start > 5:
                key = "summary"

            if key not in streams:
                streams[key] = []

            streams[key].append({
                "jitter": jitter,
                "lost": lost,
                "sent": sent,
                "throughput-bits": throughput_bits,
                "throughput-bytes": throughput_bytes,
                "start": interval_start,
                "end": interval_end,
                "stream-id": stream_id
            })

    if not streams:
        results["succeeded"] = False
        results["error"] = "No results found"
        return results

    summary_interval = None
    intervals = []

    for interval in streams:

        summary_stream = None

        interval_streams = []

        # try to find the SUM if possible
        for stream in streams[interval]:
            if stream['stream-id'] == "SUM":
                summary_stream = stream
            else:
                interval_streams.append(stream)

        # if we couldn't find it, there was probably
        # just the one line so use that
        if not summary_stream and len(interval_streams) == 1:
            summary_stream = interval_streams[0]

        finalized = {"streams": interval_streams, "summary": summary_stream}

        if interval == "summary":
            summary_interval = finalized
        else:
            intervals.append(finalized)

    logger.debug(intervals)

    # sort according to start interval
    intervals.sort(key=lambda x: x['summary']['start'])

    results["intervals"] = intervals
    results["summary"] = summary_interval

    return results
Пример #6
0
def parse_output(lines):
    results = {}
    results['succeeded'] = True

    intervals = []
    summary_view = {}

    current_interval_start = 0
    for line in lines:

        # Example line:
        # 216.8125 MB /   1.00 sec = 1817.8571 Mbps    45 retrans    206 KB-cwnd
        test = re.match(
            '^.* (\d+)\.\d+ sec \=\s*(\d+(\.\d+)?) (\S)bps\s*(\d+) retrans(\s*(\d+)\s*(\S)\S\-cwnd)?',
            line)
        if test:
            spacing = int(test.group(1))
            value = test.group(2)
            si = test.group(4)
            retrans = int(test.group(5))
            cwnd = test.group(7)
            cwnd_si = test.group(8)

            value = pscheduler.si_as_number("%s%s" % (value, si))
            cwnd = pscheduler.si_as_number("%s%s" % (cwnd, cwnd_si))

            data = {
                "start": current_interval_start,
                "end": current_interval_start + spacing,
                "stream-id":
                1,  # nuttcp won't report separate streams as best as I can tell, so just fudge it
                "throughput-bits": value,
                "tcp-window-size": cwnd,
                "retransmits": retrans
            }

            # since it doesn't report 1-2, 3-4, etc we have to keep track of where we are ourselves
            current_interval_start += spacing

            # in nuttcp there's only ever one reported and it's the summary so
            # just double it up
            intervals.append({"summary": data, "streams": [data]})

        # Example UDP line
        # 25.1572 MB /   1.00 sec =  211.0065 Mbps    62 / 25823 ~drop/pkt  0.24 ~%loss 4.8672 msMaxJitter
        test = re.match(
            '^.* (\d+)\.\d+ sec \=\s*(\d+(\.\d+)?) (\S)bps\s*(\d+) / (\d+) ~drop/pkt\s*(\d+\.\d+) ~%loss\s*(\d+\.\d+) msMaxJitter',
            line)
        if test:
            spacing = int(test.group(1))
            value = test.group(2)
            si = test.group(4)
            lost = int(test.group(5))
            sent = int(test.group(6))
            loss = test.group(7)
            jitter = float(test.group(8))

            value = pscheduler.si_as_number("%s%s" % (value, si))

            data = {
                "start": current_interval_start,
                "end": current_interval_start + spacing,
                "stream-id":
                1,  # nuttcp won't report separate streams as best as I can tell, so just fudge it
                "throughput-bits": value,
                "sent": sent,
                "lost": lost,
                "jitter": jitter
            }

            # since it doesn't report 1-2, 3-4, etc we have to keep track of where we are ourselves
            current_interval_start += spacing

            # in nuttcp there's only ever one reported and it's the summary so
            # just double it up
            intervals.append({"summary": data, "streams": [data]})

        # Example summary line:
        # 2197.0657 MB /  10.00 sec = 1842.3790 Mbps 8 %TX 90 %RX 90 retrans 237 KB-cwnd 0.50 msRTT
        test = re.match(
            '^.* (\d+)\.\d+ sec =\s*(\d+(\.\d+)?) (\S)bps \d+ %TX \d+ %RX (\d+) retrans(\s*(\d+)\s*(\S)\S\-cwnd)?',
            line)
        if test:
            duration = int(test.group(1))
            value = test.group(2)
            si = test.group(4)
            retrans = int(test.group(5))
            cwnd = test.group(7)
            cwnd_si = test.group(8)

            value = pscheduler.si_as_number("%s%s" % (value, si))
            cwnd = pscheduler.si_as_number("%s%s" % (cwnd, cwnd_si))

            summary_view = {
                "start": 0,
                "end": duration,
                "stream-id":
                1,  # nuttcp won't report separate streams as best as I can tell, so just fudge it
                "throughput-bits": value,
                "tcp-window-size": cwnd,
                "retransmits": retrans
            }

        # Example UDP summary line
        #   252.0586 MB /  10.00 sec =  211.4462 Mbps 99 %TX 50 %RX 1485 / 259593 drop/pkt 0.57 %loss 37.2012 msMaxJitter
        test = re.match(
            '^.* (\d+)\.\d+ sec \=\s*(\d+(\.\d+)?) (\S)bps\s*(\d+) %TX (\d+) %RX (\d+) / (\d+) drop/pkt\s*(\d+\.\d+) %loss\s*(\d+\.\d+) msMaxJitter',
            line)
        if test:
            duration = int(test.group(1))
            value = test.group(2)
            si = test.group(4)
            lost = int(test.group(7))
            sent = int(test.group(8))
            loss = test.group(9)
            jitter = float(test.group(10))

            value = pscheduler.si_as_number("%s%s" % (value, si))

            summary_view = {
                "start": 0,
                "end": duration,
                "stream-id":
                1,  # nuttcp won't report separate streams as best as I can tell, so just fudge it
                "throughput-bits": value,
                "sent": sent,
                "lost": lost,
                "jitter": jitter
            }

    results["intervals"] = intervals
    results["summary"] = {"summary": summary_view, "streams": [summary_view]}

    return results
Пример #7
0
def parse_output(lines):
    results = {}
    results['succeeded'] = True

    intervals = []
    summary_view = {}

    current_interval_start = 0
    for line in lines:

        # Example line:
        # 216.8125 MB /   1.00 sec = 1817.8571 Mbps    45 retrans    206 KB-cwnd
        test = re.match('^.*(\d+)\.\d+ sec \=\s*(\d+(\.\d+)?) (\S)bps\s*(\d+) retrans(\s*(\d+)\s*(\S)\S\-cwnd)?', line)
        if test:
            spacing = int(test.group(1))
            value   = test.group(2)
            si      = test.group(4)
            retrans = int(test.group(5))
            cwnd    = test.group(7)
            cwnd_si = test.group(8)

            value = pscheduler.si_as_number("%s%s" % (value, si))
            cwnd  = pscheduler.si_as_number("%s%s" % (cwnd, cwnd_si))

            data = {
                "start": current_interval_start,
                "end": current_interval_start + spacing,
                "stream-id": 1, # nuttcp won't report separate streams as best as I can tell, so just fudge it
                "throughput-bits": value,
                "tcp-window-size": cwnd,
                "retransmits": retrans
                }

            # since it doesn't report 1-2, 3-4, etc we have to keep track of where we are ourselves
            current_interval_start += spacing

            # in nuttcp there's only ever one reported and it's the summary so
            # just double it up
            intervals.append({"summary": data,
                              "streams": [data]})
            

        # Example UDP line
        # 25.1572 MB /   1.00 sec =  211.0065 Mbps    62 / 25823 ~drop/pkt  0.24 ~%loss 4.8672 msMaxJitter
        test = re.match('^.*(\d+)\.\d+ sec \=\s*(\d+(\.\d+)?) (\S)bps\s*(\d+) / (\d+) ~drop/pkt\s*(\d+\.\d+) ~%loss\s*(\d+\.\d+) msMaxJitter', line)
        if test:
            spacing = int(test.group(1))
            value   = test.group(2)
            si      = test.group(4)
            lost    = int(test.group(5))
            sent    = int(test.group(6))
            loss    = test.group(7)
            jitter  = float(test.group(8))

            value = pscheduler.si_as_number("%s%s" % (value, si))

            data = {
                "start": current_interval_start,
                "end": current_interval_start + spacing,
                "stream-id": 1, # nuttcp won't report separate streams as best as I can tell, so just fudge it
                "throughput-bits": value,
                "sent": sent,
                "lost": lost,
                "jitter": jitter
                }

            # since it doesn't report 1-2, 3-4, etc we have to keep track of where we are ourselves
            current_interval_start += spacing

            # in nuttcp there's only ever one reported and it's the summary so
            # just double it up
            intervals.append({"summary": data,
                              "streams": [data]})
        
        # Example summary line:
        # 2197.0657 MB /  10.00 sec = 1842.3790 Mbps 8 %TX 90 %RX 90 retrans 237 KB-cwnd 0.50 msRTT
        test = re.match('^.*(\d+)\.\d+ sec = (\d+(\.\d+)?) (\S)bps \d+ %TX \d+ %RX (\d+) retrans(\s*(\d+)\s*(\S)\S\-cwnd)?', line)
        if test:
            duration = int(test.group(1))
            value    = test.group(2)
            si       = test.group(4)
            retrans  = int(test.group(5))
            cwnd     = test.group(7)
            cwnd_si  = test.group(8)
           
            value = pscheduler.si_as_number("%s%s" % (value, si))
            cwnd  = pscheduler.si_as_number("%s%s" % (cwnd, cwnd_si))

            summary_view = {
                "start": 0,
                "end": duration,
                "stream-id": 1, # nuttcp won't report separate streams as best as I can tell, so just fudge it
                "throughput-bits": value,
                "tcp-window-size": cwnd,
                "retransmits": retrans
                }


        # Example UDP summary line
        #   252.0586 MB /  10.00 sec =  211.4462 Mbps 99 %TX 50 %RX 1485 / 259593 drop/pkt 0.57 %loss 37.2012 msMaxJitter
        test = re.match('^.*(\d+)\.\d+ sec \=\s*(\d+(\.\d+)?) (\S)bps\s*(\d+) %TX (\d+) %RX (\d+) / (\d+) drop/pkt\s*(\d+\.\d+) %loss\s*(\d+\.\d+) msMaxJitter', line)
        if test:
            duration = int(test.group(1))
            value    = test.group(2)
            si       = test.group(4)
            lost     = int(test.group(5))
            sent     = int(test.group(6))
            loss     = test.group(7)
            jitter   = float(test.group(8))

            value = pscheduler.si_as_number("%s%s" % (value, si))

            summary_view = {
                "start": 0,
                "end": duration,
                "stream-id": 1, # nuttcp won't report separate streams as best as I can tell, so just fudge it
                "throughput-bits": value,
                "sent": sent,
                "lost": lost,
                "jitter": jitter
                }
            

    results["intervals"] = intervals
    results["summary"]   = {"summary": summary_view,
                            "streams": [summary_view]}

    return results
Пример #8
0
def parse_output(lines):
    results = {}
    results['succeeded'] = True

    seen_header = False
    streams    = {}

    dest_ip   = None
    dest_port = None
    src_ip    = None
    src_port  = None

    for line in lines:

        # ignore bogus sessions
        if re.match('\(nan%\)', line):
            results["succeeded"] = False
            results["error"]    = "Found NaN result";
            break;

        if re.match('read failed: Connection refused', line):
            results["succeeded"] = False
            results["error"]     = "Connection refused"
            break

        test = re.match('local ([^ ]+) port (\d+) connected with ([^ ]+) port (\d+)', line)
        if test:
            dest_ip   = test.group(1)
            dest_port = test.group(2)
            src_ip    = test.group(3)
            src_port  = test.group(4)

        # Example lines
        # TCP window size:  244 KByte (WARNING: requested 64.0 MByte)
        # TCP window size: 19800 Byte (default)
        test = re.match('TCP window size:\s+(\d+(\.\d+)?) (\S)?Byte(.*\(WARNING:\s+requested\s+(\d+(\.\d+)?) (\S)?Byte)?', line)
        if test:
            window_size = test.group(1)
            window_si   = test.group(3)

            request_size = test.group(5)
            request_si   = test.group(7)

            if window_si:
                window_size = pscheduler.si_as_number("%s%s" % (window_size, window_si))

            if request_size:
                if request_si:
                    request_size = pscheduler.si_as_number("%s%s" % (request_size, request_si))
                results["requested-tcp-window-size"] = int(request_size)

            results["tcp-window-size"] = int(window_size)

        # Example line
        # [  3] MSS size 1448 bytes (MTU 1500 bytes, ethernet)
        test = re.match('.*MSS size (\d+) bytes \(MTU (\d+) bytes', line)
        if test:
            results['mss'] = int(test.group(1))
            results['mtu'] = int(test.group(2))


        stream_id        = None
        interval_start   = None
        throughput_bytes = None
        si_bytes         = None
        throughput_bits  = None
        si_bits          = None
        jitter           = None
        lost             = None
        sent             = None

        # Example line
        # [  3] 16.0-17.0 sec  37355520 Bytes  298844160 bits/sec
        test = re.match('\[\s*(\d+|SUM)\s*\]\s+([0-9\.]+)\s*\-\s*([0-9\.]+)\s+sec\s+(\d+(\.\d+)?)\s+(P|T|G|M|K)?Bytes\s+(\d+(\.\d+)?)\s+(P|T|G|M|K)?bits\/sec(\s+([0-9\.]+)\s+ms\s+(\d+)\/\s*(\d+)\s+)?', line)
        if test:
            stream_id         = test.group(1)
            interval_start    = float(test.group(2))
            interval_end      = float(test.group(3))
            throughput_bytes  = float(test.group(4))
            si_bytes          = test.group(6)
            throughput_bits   = float(test.group(7))
            si_bits           = test.group(9)
            
            # these may or may not be present depending on versions
            jitter = test.group(11)
            lost   = test.group(12)
            send   = test.group(13)

            # If the output was in say GBytes convert back to regular Bytes for ease
            # of things later
            if si_bytes:
                throughput_bytes = pscheduler.si_as_number("%s%s" % (throughput_bytes, si_bytes))
            if si_bits:
                throughput_bits = pscheduler.si_as_number("%s%s" % (throughput_bits, si_bits))

        # if we found a matching line, we can add this info to our streams
        if stream_id:

            key = "%s-%s" % (interval_start, interval_end)

            # there has to be a better way than this...
            if interval_end - interval_start > 5:
                key = "summary"

            if not streams.has_key(key):
                streams[key] = []

            streams[key].append({"jitter": jitter,
                                 "lost": lost,
                                 "sent": sent,
                                 "throughput-bits": throughput_bits,
                                 "throughput-bytes": throughput_bytes,
                                 "start": interval_start,
                                 "end": interval_end,
                                 "stream-id": stream_id})

        

    if len(streams.keys()) == 0:
        results["succeeded"] = False
        results["error"] = "No results found"
        return results


    summary_interval = None
    intervals        = []

    for interval in streams.keys():

        summary_stream = None

        interval_streams = []

        # try to find the SUM if possible
        for stream in streams[interval]:
            if stream['stream-id'] == "SUM":
                summary_stream = stream
            else:
                interval_streams.append(stream)
                
 
        # if we couldn't find it, there was probably
        # just the one line so use that
        if not summary_stream and len(interval_streams) == 1:
            summary_stream = interval_streams[0]

        finalized = {
            "streams": interval_streams,
            "summary": summary_stream
        }

        if interval == "summary":
            summary_interval = finalized
        else:
            intervals.append(finalized)


    logger.debug(intervals)

    # sort according to start interval
    intervals.sort(key = lambda x: x['summary']['start'])

    
    results["intervals"] = intervals
    results["summary"]   = summary_interval

    return results