Skip to content

Commit

Permalink
Added protocol parameter to latency and latencybg. #1378
Browse files Browse the repository at this point in the history
  • Loading branch information
mfeit-internet2 committed Feb 8, 2024
1 parent c181bbd commit e9bd083
Show file tree
Hide file tree
Showing 14 changed files with 503 additions and 247 deletions.
17 changes: 13 additions & 4 deletions pscheduler-test-latency/latency/cli-to-spec
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ opt_parser.add_option("--dest-node",
action="store", type="string",
dest="dest_node")

opt_parser.add_option("--protocol",
help="The protocol to use in making the measurement",
action="store", type="str",
dest="protocol")

opt_parser.add_option("-c", "--packet-count",
help="The number of packets to send",
action="store", type="int",
Expand Down Expand Up @@ -111,7 +116,7 @@ opt_parser.add_option("-b", "--bucket-width",
help="The bin size to use for histogram calculations. This value is divided into the result as reported in seconds and truncated to the nearest 2 decimal places.",
action="store", type="float",
dest="bucket_width")

opt_parser.add_option("-f", "--flip",
help="In multi-participant mode, have the dest start the client and request a reverse test. Useful in some firewall and NAT environments.",
action="store_true", dest="flip", default=False)
Expand All @@ -127,7 +132,7 @@ opt_parser.add_option("--traverse-nat",
opt_parser.add_option("-R", "--output-raw",
help="Output individual packet statistics. This will substantially increase the size of a successful result.",
action="store_true", dest="output_raw", default=False)

(options, remaining_args) = opt_parser.parse_args(args)

if len(remaining_args) != 0:
Expand All @@ -143,7 +148,7 @@ if options.source is not None:

if options.source_node is not None:
result['source-node'] = options.source_node

if options.dest is not None:
result['dest'] = options.dest

Expand All @@ -153,9 +158,13 @@ if options.dest_node is not None:
if options.packet_count is not None:
result['packet-count'] = options.packet_count

if options.protocol is not None:
result['protocol'] = options.protocol
spec_schema.set(4)

if options.packet_interval is not None:
result['packet-interval'] = options.packet_interval

if options.packet_timeout is not None:
result['packet-timeout'] = options.packet_timeout

Expand Down
3 changes: 3 additions & 0 deletions pscheduler-test-latency/latency/spec-format
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ Source ............... {{ unspec(source) }}
Source Node .......... {{ unspec(sourcenode) }}
Destination .......... {{ unspec(dest) }}
Destination Node ..... {{ unspec(destnode) }}
{% if schema >= 4 -%}
Protocol ............. {{ unspec(protocol) }}
{%- endif %}
Packet Count ......... {{ unspec(packetcount) }}
Packet Interval ...... {{ unspec(packetinterval) }}
Packet Timeout ....... {{ unspec(packettimeout) }}
Expand Down
116 changes: 101 additions & 15 deletions pscheduler-test-latency/latency/validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

from pscheduler import json_validate

MAX_SCHEMA = 3
MAX_SCHEMA = 4

SPEC_SCHEMA = {

Expand Down Expand Up @@ -60,7 +60,7 @@
"packet-interval": {
"description": "The number of seconds to delay between sending packets",
"$ref": "#/local/packet-interval"

},
"packet-timeout": {
"description": "The number of seconds to wait before declaring a packet lost",
Expand All @@ -83,12 +83,12 @@
"$ref": "#/pScheduler/IPTOS"
},
"ip-version": {
"description": "Force a specific IP address type used performing the test. Useful when specifying hostnames as source or dest that may map to both IPv4 and IPv6 addresses.",
"$ref": "#/pScheduler/ip-version"
"description": "Force a specific IP address type used performing the test. Useful when specifying hostnames as source or dest that may map to both IPv4 and IPv6 addresses.",
"$ref": "#/pScheduler/ip-version"
},
"bucket-width": {
"description": "The bin size to use for histogram calculations. This value is divided into the result as reported in seconds and truncated to the nearest 2 decimal places.",
"$ref": "#/local/bucket-width"
"$ref": "#/local/bucket-width"
},
"output-raw": {
"description": "Output individual packet statistics. This will substantially increase the size of a successful result.",
Expand Down Expand Up @@ -135,7 +135,7 @@
"packet-interval": {
"description": "The number of seconds to delay between sending packets",
"$ref": "#/local/packet-interval"

},
"packet-timeout": {
"description": "The number of seconds to wait before declaring a packet lost",
Expand All @@ -158,12 +158,12 @@
"$ref": "#/pScheduler/IPTOS"
},
"ip-version": {
"description": "Force a specific IP address type used performing the test. Useful when specifying hostnames as source or dest that may map to both IPv4 and IPv6 addresses.",
"$ref": "#/pScheduler/ip-version"
"description": "Force a specific IP address type used performing the test. Useful when specifying hostnames as source or dest that may map to both IPv4 and IPv6 addresses.",
"$ref": "#/pScheduler/ip-version"
},
"bucket-width": {
"description": "The bin size to use for histogram calculations. This value is divided into the result as reported in seconds and truncated to the nearest 2 decimal places.",
"$ref": "#/local/bucket-width"
"$ref": "#/local/bucket-width"
},
"output-raw": {
"description": "Output individual packet statistics. This will substantially increase the size of a successful result.",
Expand Down Expand Up @@ -214,7 +214,93 @@
"packet-interval": {
"description": "The number of seconds to delay between sending packets",
"$ref": "#/local/packet-interval"


},
"packet-timeout": {
"description": "The number of seconds to wait before declaring a packet lost",
"$ref": "#/pScheduler/CardinalZero"
},
"packet-padding": {
"description": "The size of padding to add to the packet in bytes",
"$ref": "#/pScheduler/CardinalZero"
},
"ctrl-port": {
"description": "The control plane port to use for the entity acting as the server (the dest if flip is not set, the source otherwise)",
"$ref": "#/pScheduler/IPPort"
},
"data-ports": {
"description": "The port range to use on the side of the test running the client. At least two ports required.",
"$ref": "#/pScheduler/IPPortRange"
},
"ip-tos": {
"description": "DSCP value for TOS byte in the IP header as an integer",
"$ref": "#/pScheduler/IPTOS"
},
"ip-version": {
"description": "Force a specific IP address type used performing the test. Useful when specifying hostnames as source or dest that may map to both IPv4 and IPv6 addresses.",
"$ref": "#/pScheduler/ip-version"
},
"bucket-width": {
"description": "The bin size to use for histogram calculations. This value is divided into the result as reported in seconds and truncated to the nearest 2 decimal places.",
"$ref": "#/local/bucket-width"
},
"output-raw": {
"description": "Output individual packet statistics. This will substantially increase the size of a successful result.",
"$ref": "#/pScheduler/Boolean"
},
"flip": {
"description": "In multi-participant mode, have the dest start the client and request a reverse test. Useful in some firewall and NAT environments.",
"$ref": "#/pScheduler/Boolean"
},
"reverse": {
"description": "Report results in the reverse direction (destination to source) if possible.",
"$ref": "#/pScheduler/Boolean"
},
"traverse-nat": {
"description": "Make an effort to traverse outbound NAT,",
"$ref": "#/pScheduler/Boolean"
},
},
"required": ["schema", "dest"],
"additionalProperties": False
},

"v4": {
"type": "object",
"properties": {
"schema": {
"description": "The version of the schema",
"type": "integer",
"enum": [ 4 ]
},
"source": {
"description": "The address of the entity sending packets in this test",
"$ref": "#/pScheduler/Host"
},
"source-node": {
"description": "The address of the source pScheduler node, if different",
"$ref": "#/pScheduler/URLHostPort"
},
"dest": {
"description": "The address of the entity receiving packets in this test",
"$ref": "#/pScheduler/Host"
},
"dest-node": {
"description": "The address of the destination pScheduler node, if different",
"$ref": "#/pScheduler/URLHostPort"
},
"protocol": {
"description": "The protocol to use in making the measurement",
"$ref": "#/pScheduler/String"
},
"packet-count": {
"description": "The number of packets to send",
"$ref": "#/pScheduler/Cardinal"
},
"packet-interval": {
"description": "The number of seconds to delay between sending packets",
"$ref": "#/local/packet-interval"

},
"packet-timeout": {
"description": "The number of seconds to wait before declaring a packet lost",
Expand All @@ -237,12 +323,12 @@
"$ref": "#/pScheduler/IPTOS"
},
"ip-version": {
"description": "Force a specific IP address type used performing the test. Useful when specifying hostnames as source or dest that may map to both IPv4 and IPv6 addresses.",
"$ref": "#/pScheduler/ip-version"
"description": "Force a specific IP address type used performing the test. Useful when specifying hostnames as source or dest that may map to both IPv4 and IPv6 addresses.",
"$ref": "#/pScheduler/ip-version"
},
"bucket-width": {
"description": "The bin size to use for histogram calculations. This value is divided into the result as reported in seconds and truncated to the nearest 2 decimal places.",
"$ref": "#/local/bucket-width"
"$ref": "#/local/bucket-width"
},
"output-raw": {
"description": "Output individual packet statistics. This will substantially increase the size of a successful result.",
Expand Down Expand Up @@ -292,7 +378,7 @@
},
"ip-ttl": {
"type": "integer",
"minimum": 0,
"minimum": 0,
"maximum": 255
}
},
Expand Down Expand Up @@ -407,5 +493,5 @@ def spec_is_valid(json):
return json_validate(json, temp_schema, max_schema=MAX_SCHEMA)


def result_is_valid(json):
def result_is_valid(json):
return json_validate(json, RESPONSE_SCHEMA)
13 changes: 12 additions & 1 deletion pscheduler-test-latencybg/latencybg/cli-to-spec
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ opt_parser.add_option("--dest-node",
action="store", type="string",
dest="dest_node")

opt_parser.add_option("--protocol",
help="The protocol to use in making the measurement",
action="store", type="str",
dest="protocol")

opt_parser.add_option("-c", "--packet-count",
help="The number of packets to send",
action="store", type="int",
Expand Down Expand Up @@ -132,7 +137,8 @@ if len(remaining_args) != 0:
pscheduler.fail("Unusable arguments: %s" % " ".join(remaining_args))


result = { 'schema': 1 }
result = { }
schema = pscheduler.HighInteger(1)

if options.source is not None:
result['source'] = options.source
Expand All @@ -159,6 +165,10 @@ if options.duration is not None:
if options.packet_count is not None:
result['packet-count'] = options.packet_count

if options.protocol is not None:
result['protocol'] = options.protocol
schema.set(2)

if options.packet_interval is not None:
result['packet-interval'] = options.packet_interval

Expand Down Expand Up @@ -199,5 +209,6 @@ if options.flip:
if options.output_raw:
result['output-raw'] = options.output_raw

result['schema'] = schema.value()

pscheduler.succeed_json(result)
3 changes: 2 additions & 1 deletion pscheduler-test-latencybg/latencybg/result-format
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import pscheduler
import sys
import math
from validate import result_max_schema
from validate import result_is_valid

'''
Expand Down Expand Up @@ -147,7 +148,7 @@ if format != 'text/plain':
pscheduler.fail("Unsupported format '%s'" % format)

#parse JSON input
input = pscheduler.json_load(exit_on_error=True, max_schema=1)
input = pscheduler.json_load(exit_on_error=True, max_schema=result_max_schema())

#validate against JSON schema file
if "result" not in input:
Expand Down
7 changes: 5 additions & 2 deletions pscheduler-test-latencybg/latencybg/spec-format
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@

import pscheduler

from validate import spec_max_schema
from validate import spec_is_valid
from validate import MAX_SCHEMA

TEMPLATE='''
{% if _mime_type == 'text/plain' %}
Expand All @@ -16,6 +16,9 @@ Source Node .......... {{ unspec(sourcenode) }}
Destination .......... {{ unspec(dest) }}
Destination Node ..... {{ unspec(destnode) }}
Duration ............. {{ unspec(duration) }}
{% if schema >= 2 -%}
Protocol ............. {{ unspec(protocol) }}
{%- endif %}
Packet Count ......... {{ unspec(packetcount) }}
Packet Interval ...... {{ unspec(packetinterval) }}
Packet Timeout ....... {{ unspec(packettimeout) }}
Expand Down Expand Up @@ -64,4 +67,4 @@ Flip Mode ............ {{ unspec(flip) }}
{% endif %}
'''

pscheduler.spec_format_method(TEMPLATE, max_schema=MAX_SCHEMA, validator=spec_is_valid)
pscheduler.spec_format_method(TEMPLATE, max_schema=spec_max_schema(), validator=spec_is_valid)
3 changes: 2 additions & 1 deletion pscheduler-test-latencybg/latencybg/spec-is-valid
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
import pscheduler

from validate import spec_is_valid
from validate import spec_max_schema


try:
json = pscheduler.json_load(max_schema=1)
json = pscheduler.json_load(max_schema=spec_max_schema())
except ValueError as ex:
pscheduler.succeed_json({
"valid": False,
Expand Down
16 changes: 11 additions & 5 deletions pscheduler-test-latencybg/latencybg/spec-to-cli
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
# Convert a test specification to command-line options

import pscheduler
import jsonschema
from validate import spec_is_valid, REQUEST_SCHEMA

from validate import spec_is_valid
from validate import spec_max_schema
from validate import SPEC_SCHEMA

#load spec JSON
spec = pscheduler.json_load(exit_on_error=True, max_schema=1)
spec = pscheduler.json_load(exit_on_error=True, max_schema=spec_max_schema())
if not isinstance(spec, dict):
pscheduler.fail("Invalid JSON for this operation")

Expand All @@ -17,8 +19,12 @@ if not valid:
pscheduler.fail(message)

#get properties from schema
schema_props = REQUEST_SCHEMA.get('properties', {})
if not schema_props:
spec_version = spec.get('schema', 1)
try:
# It's safe to assume that the schema version is valid because it
# passed validation above.
schema_props = SPEC_SCHEMA['versions'][str(spec_version)]['properties']
except KeyError:
pscheduler.fail("Error retrieving schema properties")

#build command-line from schema
Expand Down
Loading

0 comments on commit e9bd083

Please sign in to comment.