Folks: Manish <[email protected]> contributed test cases
7, 8, 9, and 18 (thanks, Manish).
With this contribution, the ALTO test document is almost
complete, except for one more test case --- Test Case 19.
The current test case document (version 0.9) is attached.
Please take a look at the newly added test cases (7, 8, 9, and
18) and make sure these look reasonable.
Thanks,
- vijay
--
Vijay K. Gurbani, Bell Laboratories, Alcatel-Lucent
1960 Lucent Lane, Rm. 9C-533, Naperville, Illinois 60566 (USA)
Email: vkg@{bell-labs.com,acm.org} / [email protected]
Web: http://ect.bell-labs.com/who/vkg/
---- BEGIN ALTO INTEROPERABILITY DOCUMENT (Version 0.9)
For the ALTO interoperability, we will consider the following topology
from the view point of a service provider:
PID IP Address Block
-------------------------------
mypid1 10.0.0.0/8, 15.0.0.0/8
mypid2 192.168.0.0/16
mypid3 192.168.10.0/24
peeringpid1 128.0.0.0/16
peeringpid2 130.0.0.0/16, 2001:DB8::/32
transitpid1 132.0.0.0/16
transitpid2 135.0.0.0/16
defaultpid 0.0.0.0/0, ::/0
And here is the cost map for the above topology:
Source PID Destination PID Cost (mode: numerical)
--------------------------------------------------------------------
mypid1 mypid1 0
" mypid2 0
" mypid3 0
" peeringpid1 0
" peeringpid2 0
" transitpid1 5
" transitpid2 10
" defaultpid 4
mypid2 mypid1 0
" mypid2 0
" mypid3 0
" peeringpid1 0
" peeringpid2 0
" transitpid1 7
" transitpid2 8
" defaultpid 4
mypid3 mypid1 0
" mypid2 0
" mypid3 0
" peeringpid1 0
" peeringpid2 0
" transitpid1 8
" transitpid2 8
" defaultpid 5.1
Test Cases
1) Retrieving the Information Resource Directory (IRD, Section 7.6)
- Client retrieve IRD through a well known URI:
http://alto.ietf.org/directory
using a request shown below:
GET /directory HTTP/1.1
Host: alto.ietf.org
Accept: application/alto-directory+json,application/alto-error+json
- Server returns the following directory:
HTTP/1.1 200 OK
Content-Length: 2596
Connection: close
Content-Type: application/alto-directory+json
Date: Wed, 29 Jun 2011 10:52:09 GMT
{
"resources": [
{
"capabilities": {
"cost-modes": [
"numerical"
],
"cost-types": [
"routingcost"
]
},
"media-types": [
"application/alto-costmap+json"
],
"uri": "http://alto.ietf.org/costmap/numerical/routingcost"
},
{
"capabilities": {
"cost-modes": [
"ordinal"
],
"cost-types": [
"routingcost"
]
},
"media-types": [
"application/alto-costmap+json"
],
"uri": "http://alto.ietf.org/costmap/ordinal/routingcost"
},
{
"media-types": [
"application/alto-networkmap+json"
],
"uri": "http://alto.ietf.org/networkmap"
},
{
"media-types": [
"application/alto-serverinfo+json"
],
"uri": "http://alto.ietf.org/serverinfo"
},
{
"accepts": [
"application/alto-costmapfilter+json"
],
"capabilities": {
"cost-constraints": true,
"cost-modes": [
"numerical",
"ordinal"
],
"cost-types": [
"routingcost"
]
},
"media-types": [
"application/alto-costmap+json"
],
"uri": "http://alto.ietf.org/costmap/filtered"
},
{
"accepts": [
"application/alto-endpointcostparams+json"
],
"capabilities": {
"cost-constraints": true,
"cost-modes": [
"numerical",
"ordinal"
],
"cost-types": [
"routingcost"
]
},
"media-types": [
"application/alto-endpointcost+json"
],
"uri": "http://alto.ietf.org/endpoints/cost"
},
{
"accepts": [
"application/alto-endpointpropparams+json"
],
"capabilities": {
"prop-types": [
"pid"
]
},
"media-types": [
"application/alto-endpointprop+json"
],
"uri": "http://alto.ietf.org/endpoints/property"
},
{
"accepts": [
"application/alto-networkmapfilter+json"
],
"media-types": [
"application/alto-networkmap+json"
],
"uri": "http://alto.ietf.org/networkmap/filtered"
}
]
}
2) Longest prefix match (c.f. Section 4.2.1)
- Client retrieves a PID for IP address 192.168.1.23
Use the following request:
POST /endpointprop/lookup HTTP/1.1
Host: alto.ietf.org
Content-Length: ...
Accept: application/alto-endpointprop+json
{
"properties" : [ "pid" ],
"endpoints" : [ "ipv4:192.168.1.23" ]
}
- Server returns mypid2 using the following response:
HTTP/1.1 200 OK
Content-Length: ...
Content-Type: application/alto-endpointprop+json
{
"meta" : {},
"data": {
"ipv4:192.168.1.23" : { "pid": "mypid2" }
}
}
3) Longest prefix match (c.f. Section 4.2.1)
- Client retrieves a PID for IP address 192.168.10.23
Use the following request:
POST /endpointprop/lookup HTTP/1.1
Host: alto.ietf.org
Content-Length: ...
Accept: application/alto-endpointprop+json
{
"properties" : [ "pid" ],
"endpoints" : [ "ipv4:192.168.10.23" ]
}
- Server returns mypid3 using the following response:
HTTP/1.1 200 OK
Content-Length: ...
Content-Type: application/alto-endpointprop+json
{
"meta" : {},
"data": {
"ipv4:192.168.10.23" : { "pid": "mypid3" }
}
}
4) Returning default PID:
- Client retrieves a PID for IP address 201.1.13.12
Use the following request:
POST /endpointprop/lookup HTTP/1.1
Host: alto.ietf.org
Content-Length: ...
Accept: application/alto-endpointprop+json
{
"properties" : [ "pid" ],
"endpoints" : [ "ipv4:201.1.13.12" ]
}
- Server returns defaultpid using the following response:
HTTP/1.1 200 OK
Content-Length: ...
Content-Type: application/alto-endpointprop+json
{
"meta" : {},
"data": {
"ipv4:201.1.13.12" : { "pid": "defaultpid" }
}
}
5) Retrieving a network map (Section 4, Section 7.7.2)
- Client uses information from IRD to retrieve a network map.
Use the following request:
GET /networkmap HTTP/1.1
Host: alto.ietf.org
Accept: application/alto-networkmap+json,application/alto-error+json
- Server returns the following:
HTTP/1.1 200 OK
Content-Length: 799
Content-Type: application/alto-networkmap+json
{
"meta" : {},
"data" : {
"map-vtag" : "1266506139",
"map" : {
"mypid1" : {
"ipv4" : [ "10.0.0.0/8", "15.0.0.0/8" ]
},
"mypid2" : {
"ipv4" : [ "192.168.0.0/16" ]
},
"mypid3" : {
"ipv4" : [ "192.168.10.0/24" ]
},
"peeringpid1" : {
"ipv4" : [ "128.0.0.0/16" ]
},
"peeringpid2" : {
"ipv4" : [ "130.0.0.0/16" ],
"ipv6" : [ "2001:DB8::/32"]
},
"transitpid1" : {
"ipv4" : [ "132.0.0.0/16" ]
},
"transitpid2" : {
"ipv4" : [ "135.0.0.0/16" ]
},
"defaultpid" : {
"ipv4" : [ "0.0.0.0/0" ],
"ipv6" : [ "::/0" ]
}
}
}
}
6) Retrieving a cost map (Section 5)
- Client uses information from IRD to retrieve a cost map.
Use the following request:
GET /costmap/num/routingcost HTTP/1.1
Host: alto.ietf.org
Accept: application/alto-costmap+json,application/alto-error+json
- Server returns the following:
HTTP/1.1 200 OK
Content-Length: 787
Content-Type: application/alto-costmap+json
{
"meta" : {},
"data" : {
"cost-mode" : "numerical",
"cost-type" : "routingcost",
"map-vtag" : "1266506139",
"map" : {
"mypid1": { "mypid1" : 0, "mypid2" : 0, "mypid3" : 0,
"peeringpid1" : 0, "peerinpid2" : 0,
"transitpid1" : 5, "transitpid2" : 10,
"defaultpid" : 4},
"mypid2": { "mypid1" : 0, "mypid2" : 0, "mypid3" : 0,
"peeringpid1" : 0, "peerinpid2" : 0,
"transitpid1" : 7, "transitpid2" : 8,
"defaultpid" : 4},
"mypid3": { "mypid1" : 0, "mypid2" : 0, "mypid3" : 0,
"peeringpid1" : 0, "peerinpid2" : 0,
"transitpid1" : 8, "transitpid2" : 8,
"defaultpid" : 5.1}
}
}
}
NOTE: Make sure that the vtag in the response for the cost
map is the same as the vtag in the response for Test case 5.
7) Error: JSON parsing error (Section 7)
- Client sends a malformed JSON body in the request --- a missing
closing '}'
Use the following request:
POST /endpointcost/lookup HTTP/1.1
Host: alto.ietf.org
Accept: application/alto-endpointcost+json,application/alto-error+json
Content-Type: application/alto-endpointcostparams+json
Content-Length: 131
{
"cost-mode" : "numerical",
"cost-type" : "routingcost",
"endpoints": {
"srcs": [ "ipv4:10.0.0.0"],
"dsts": [ "ipv4:10.0.0.0" ]
}
- Server returns HTTP response code of 400 with ALTO error code
of E_SYNTAX (c.f., Table 1):
HTTP/1.1 400 Bad Request
Content-Type: application/alto-error+json
Content-Length: 60
{
"code": "E_SYNTAX",
"reason": "Parsing error in request"
}
Note that a server implementation can provide a more descriptive
phrase, if desired. For instance, in the above example, a
reason phrase of "Parsing error: Missing closing brace" may be
more descriptive.
8) Error: Required field missing (Section 7)
- Client sends a request with a missing field --- no "cost-mode".
Use the following request:
POST /endpointcost/lookup HTTP/1.1
Host: alto.ietf.org
Accept: application/alto-endpointcost+json,application/alto-error+json
Content-Type: application/alto-endpointcostparams+json
Content-Length: 105
{
"cost-type" : "routingcost",
"endpoints": {
"srcs": [ "ipv4:10.0.0.0"],
"dsts": [ "ipv4:10.0.0.0" ]
}
}
- Server returns HTTP response code of 400 with ALTO error code
of E_JSON_FIELD_MISSING (c.f., Table 1):
HTTP/1.1 400 Bad Request
Content-Type: application/alto-error+json
Content-Length: 70
{
"code": "E_JSON_FIELD_MISSING",
"reason": "Required field missing"
}
Note that as in Test Case 7, a server may provide a descriptive
reason phrase. In this particular example, a reason phrase of
"Missing mandatory field: cost-mode" may be more descriptive.
9) Error: Unexpected JSON value (Section 7)
- Client sends a request with a JSON value of unexpected type ---
object "srcs" is not an array type.
Use the following request:
POST /endpointcost/lookup HTTP/1.1
Host: alto.ietf.org
Accept: application/alto-endpointcost+json,application/alto-error+json
Content-Type: application/alto-endpointcostparams+json
Content-Length: 129
{
"cost-mode" : "numerical",
"cost-type" : "routingcost",
"endpoints": {
"srcs":"ipv4:10.0.0.0" ,
"dsts": [ "ipv4:10.0.0.0" ]
}
}
- Server returns HTTP response code of 400 with ALTO error code
of E_JSON_VALUE_TYPE (c.f., Table 1):
HTTP/1.1 400 Bad Request
Content-Type: application/alto-error+json
Content-Length: 74
{
"code": "E_JSON_VALUE_TYPE",
"reason": "JSON value of unexpected type"
}
10) Error: Invalid JSON cost mode (Section 7)
- Client sends a request with a cost mode of 'foo'
POST /costmap/filtered HTTP/1.1
Host: alto.ietf.org
Content-Length: ...
Content-Type: application/alto-costmapfilter+json
Accept: application/alto-costmap+json
{
"cost-mode": "foo",
"cost-type": "routingcost",
"pids": {
"dsts": [],
"srcs": []
}
}
- Server returns HTTP response code of 400 with ALTO error code
of E_JSON_COST_MODE (c.f., Table 1).
HTTP/1.1 400 Bad Request
Content-Length: ...
Content-Type: application/alto-error+json
{
"code": "E_INVALID_COST_MODE",
"reason": "Invalid cost mode"
}
11) Error: Invalid JSON cost type (Section 7)
- Client sends a request with a cost type of 'foo'
POST /costmap/filtered HTTP/1.1
Host: alto.ietf.org
Content-Length: ...
Content-Type: application/alto-costmapfilter+json
Accept: application/alto-costmap+json
{
"cost-mode": "numerical",
"cost-type": "foo",
"pids": {
"dsts": [],
"srcs": []
}
}
- Server returns HTTP response code of 400 with ALTO error code
of E_JSON_COST_TYPE (c.f., Table 1).
HTTP/1.1 400 Bad Request
Content-Length: ...
Content-Type: application/alto-error+json
{
"code": "E_INVALID_COST_TYPE",
"reason": "Invalid cost type"
}
12) Error: Invalid JSON property type (Section 7)
- Client sends a request with an invalid property type ('foo')
for IP address 10.0.0.1:
POST /endpointprops/lookup HTTP/1.1
Host: alto.ietf.org
Content-Length: ...
Content-Type: application/alto-endpointpropparams+json
Accept: application/alto-endpointprop+json
{
"endpoints": ["ipv4:10.0.0.1"],
"properties": ["foo"]
}
- Server returns HTTP response code of 400 with ALTO error code
of E_JSON_PROPERTY_TYPE (c.f., Table 1).
HTTP/1.1 400 Bad Request
Content-Length: ...
Content-Type: application/alto-error+json
{
"code": "E_INVALID_PROPERTY_TYPE",
"reason": "Invalid property type"
}
13) Error: multiple errors in request (Section 7)
- Client sends a request with an invalid cost and type and mode
('foo' and 'bar' respectively):
POST /costmap/filtered HTTP/1.1
Host: alto.ietf.org
Content-Length: ...
Content-Type: application/alto-costmapfilter+json
Accept: application/alto-costmap+json
{
"cost-mode": "bar",
"cost-type": "foo",
"pids": {
"dsts": [],
"srcs": []
}
}
- Server should detect at least one error and return that in a
response. The server chooses which error to report.
HTTP/1.1 400 Bad Request
Content-Length: ...
Content-Type: application/alto-error+json
{
"code": "E_INVALID_COST_TYPE",
"reason": "Invalid cost type"
}
Question: If the server is capable of detecting and reporting
multiple errors, then what? How does it let the client know?
14) Error: send a request with a bad URI
- Client sends the following request:
GET /foo/bar HTTP/1.1
Host: alto.ietf.org
Accept: application/alto-costmap+json,application/alto-error+json
- Server responds with:
HTTP/1.1 404 Not Found
Content-Length: 0
15) Change in network map (Section 5.3)
- Add a new network, changing the map. For example, add the following
subnet 201.1.2.0/24 to peeringpid2 giving the new network map entry
for peeringpid2 as follows:
peeringpid2 130.0.0.0/16, 2001:DB8::/32, 201.1.2.0/24
- Have a client retrieve the new network map.
- The Version tag on the network map should be different than the
one retrieved in Test Case 5.
- The server will respond with the following:
HTTP/1.1 200 OK
Content-Length: 827
Content-Type: application/alto-networkmap+json
{
"meta" : {},
"data" : {
"map-vtag" : "1266506155",
"map" : {
"mypid1" : {
"ipv4" : [ "10.0.0.0/8", "15.0.0.0/8" ]
},
"mypid2" : {
"ipv4" : [ "192.168.0.0/16" ]
},
"mypid3" : {
"ipv4" : [ "192.168.10.0/24" ]
},
"peeringpid1" : {
"ipv4" : [ "128.0.0.0/16" ]
},
"peeringpid2" : {
"ipv4" : [ "130.0.0.0/16" ],
"ipv4" : [ "201.1.2.0/24" ],
"ipv6" : [ "2001:DB8::/32"]
},
"transitpid1" : {
"ipv4" : [ "132.0.0.0/16" ]
},
"transitpid2" : {
"ipv4" : [ "135.0.0.0/16" ]
},
"defaultpid" : {
"ipv4" : [ "0.0.0.0/0" ],
"ipv6" : [ "::/0" ]
}
}
}
}
16) Filtered network map (Section 7.7.3)
- Client sends a request to get a filtered map of mypid2:
Use the following request:
POST /networkmap/filtered HTTP/1.1
Host: alto.ietf.org
Content-Length: 26
Content-Type: application/alto-networkmapfilter+json
Accept: application/alto-networkmap+json,application/alto-error+json
{
"pids": [ "mypid2" ]
}
- Server returns the following response:
HTTP/1.1 200 OK
Content-Length: 172
Content-Type: application/alto-networkmap+json
{
"meta" : {},
"data" : {
"map-vtag" : "1266506155",
"map" : {
"mypid2" : {
"ipv4" : [ "192.168.0.0/16" ]
},
}
}
}
17) Filtered cost map (Section 7.7.3.2, Section 7.7.2.2)
- Client sends a request to get a filtered cost map from a source
PID to a set of destination PIDs.
Use the following request:
POST /costmap/filtered HTTP/1.1
Host: alto.ietf.org
Content-Type: application/alto-costmapfilter+json
Content-Length: 174
Accept: application/alto-costmap+json,application/alto-error+json
{
"cost-mode" : "numerical",
"cost-type" : "routingcost",
"pids" : {
"srcs" : [ "mypid1", "mypid3" ]
"dsts" : [ "mypid2", "peeringpid1", "transitpid2" ]
}
}
- Server responds with the following:
HTTP/1.1 200 OK
Content-Length: 294
Content-Type: application/alto-costmap+json
{
"meta" : {},
"data" : {
"cost-mode" : "numerical",
"cost-type" : "routingcost",
"map-vtag" : "1266506155",
"map" : {
"mypid1": { "mypid2": 0, "peeringpid1": 0, "transitpid2": 10 },
"mypid3": { "mypid2": 0, "peeringpid1": 0, "transitpid2": 8 }
}
}
}
18) Endpoint cost service (Section 7.7.5)
- Client sends a request to get cost information between
individual endpoints.
Use the following request:
POST /endpointcost/lookup HTTP/1.1
Host: alto.example.com
Content-Length: 428
Content-Type: application/alto-endpointcostparams+json
Accept: application/alto-endpointcost+json,application/alto-error+json
{
"cost-mode" : "ordinal",
"cost-type" : "routingcost",
"endpoints" : {
"srcs": [ "ipv4:10.0.0.0", "ipv4:192.168.11.0", "ipv4:192.168.10.1"],
"dsts": [
"ipv4:10.0.0.0",
"ipv4:15.0.0.0",
"ipv4:192.168.11.0",
"ipv4:192.168.10.0",
"ipv4:128.0.0.0",
"ipv4:130.0.0.0",
"ipv4:0.0.0.0",
"ipv4:132.0.0.0",
"ipv4:135.0.0.0"
]
}
}
- Server responds with the following:
HTTP/1.1 200 OK
Content-Length: 1692
Content-Type: application/alto-endpointcost+json
{
"meta": { },
"data": {
"cost-mode": "numerical",
"cost-type": "routingcost",
"map": {
"ipv4:10.0.0.0": {
"ipv4:10.0.0.0": 0.000000,
"ipv4:15.0.0.0": 0.000000,
"ipv4:192.168.11.0": 0.000000,
"ipv4:192.168.10.0": 0.000000,
"ipv4:128.0.0.0": 0.000000,
"ipv4:130.0.0.0": 0.000000,
"ipv4:0.0.0.0": 4.000000,
"ipv4:132.0.0.0": 5.000000,
"ipv4:135.0.0.0": 10.000000
},
"ipv4:192.168.11.0": {
"ipv4:10.0.0.0": 0.000000,
"ipv4:15.0.0.0": 0.000000,
"ipv4:192.168.11.0": 0.000000,
"ipv4:192.168.10.0": 0.000000,
"ipv4:128.0.0.0": 0.000000,
"ipv4:130.0.0.0": 0.000000,
"ipv4:0.0.0.0": 4.000000,
"ipv4:132.0.0.0": 7.000000,
"ipv4:135.0.0.0": 8.000000
},
"ipv4:192.168.10.0": {
"ipv4:10.0.0.0": 0.000000,
"ipv4:15.0.0.0": 0.000000,
"ipv4:192.168.11.0": 0.000000,
"ipv4:192.168.10.0": 0.000000,
"ipv4:128.0.0.0":0.000000,
"ipv4:130.0.0.0": 0.000000,
"ipv4:0.0.0.0": 5.100000,
"ipv4:132.0.0.0": 8.000000,
"ipv4:135.0.0.0": 8.000000
}
}
}
}
19) IPv6 test cases
(TBD)
Miscellaneous notes
1) Section 4.2.1 says that "Each endpoint MUST map into exactly one PID."
What happens if a client finds out that the above is not true?
Update: This is being debated on the mailing list right now.
---- END ALTO INTEROPERABILITY DOCUMENT (Version 0.9)
_______________________________________________
alto mailing list
[email protected]
https://www.ietf.org/mailman/listinfo/alto