diff options
author | Ole Troan <ot@cisco.com> | 2020-05-20 15:47:06 +0200 |
---|---|---|
committer | Neale Ranns <nranns@cisco.com> | 2020-05-25 11:22:34 +0000 |
commit | f5db3711b28db4e364ac01be8b124dd24d573782 (patch) | |
tree | eee3c8aabae4287bf89c0e545e2400770fc223cb /src/plugins/map/test | |
parent | afc233aa93c3f23b30b756cb4ae2967f968bbbb1 (diff) |
api: add new stream message convention
Instead of having to wrap dump/detail calls in control ping, send details messages in between a normal
reply / request pair. As expressed in the below service statement.
Example:
service {
rpc map_domains_gets returns map_domains_get_reply
stream map_domain_details;
};
define map_domains_get
{
u32 client_index;
u32 context;
u32 cursor;
};
define map_domains_get_reply
{
u32 context;
i32 retval;
u32 cursor;
};
To avoid blocking the main thread for too long, the replies are now sent in client message queue size
chunks. The reply message returns VNET_API_ERROR_EAGAIN when there is more to read.
The API handler must also include a "cursor" that is used to the next call to the get function.
API handler example:
REPLY_AND_DETAILS_MACRO (VL_API_MAP_DOMAINS_GET_REPLY, mm->domains,
({
send_domain_details (cursor, rp, mp->context);
}));
The macro starts from cursor and iterates through the pool
until vl_api_process_may_suspend() returns true or the iteration
reaches the end of the list.
Client Example:
cursor = 0
d = []
while True:
rv, details = map_domains_get(cursor=cursor)
d += details
if rv.retval == 0 or rv.retval != -165:
break
cursor = rv.cursor
or the convenience iterator:
for x in vpp.details_iter(vpp.api.map_domains_get):
pass
or
list(details_iter(map_domains_get))
Change-Id: Iad9f6b41b0ef886adb584c97708dd91cf552749e
Type: feature
Signed-off-by: Ole Troan <ot@cisco.com>
Diffstat (limited to 'src/plugins/map/test')
-rw-r--r-- | src/plugins/map/test/test_map.py | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/src/plugins/map/test/test_map.py b/src/plugins/map/test/test_map.py index 59c23335052..93ea3f06976 100644 --- a/src/plugins/map/test/test_map.py +++ b/src/plugins/map/test/test_map.py @@ -100,6 +100,48 @@ class TestMAP(VppTestCase): self.assertEqual(rv[0].tag, tag, "output produced incorrect tag value.") + def create_domains(self, ip4_pfx_str, ip6_pfx_str, ip6_src_str): + ip4_pfx = ipaddress.ip_network(ip4_pfx_str) + ip6_dst = ipaddress.ip_network(ip6_pfx_str) + mod = ip4_pfx.num_addresses / 1024 + indicies = [] + for i in range(ip4_pfx.num_addresses): + rv = self.vapi.map_add_domain(ip6_prefix=ip6_pfx_str, + ip4_prefix=str(ip4_pfx[i]) + "/32", + ip6_src=ip6_src_str) + indicies.append(rv.index) + return indicies + + def test_api_map_domains_get(self): + # Create a bunch of domains + domains = self.create_domains('130.67.0.0/24', '2001::/32', + '2001::1/128') + self.assertEqual(len(domains), 256) + + d = [] + cursor = 0 + + # Invalid cursor + rv, details = self.vapi.map_domains_get(cursor=1234) + self.assertEqual(rv.retval, -7) + + # Delete a domain in the middle of walk + rv, details = self.vapi.map_domains_get(cursor=0) + self.assertEqual(rv.retval, -165) + self.vapi.map_del_domain(index=rv.cursor) + domains.remove(rv.cursor) + + # Continue at point of deleted cursor + rv, details = self.vapi.map_domains_get(cursor=rv.cursor) + self.assertEqual(rv.retval, -165) + + d = list(self.vapi.vpp.details_iter(self.vapi.map_domains_get)) + self.assertEqual(len(d), 255) + + # Clean up + for i in domains: + self.vapi.map_del_domain(index=i) + def test_map_e_udp(self): """ MAP-E UDP""" @@ -916,5 +958,6 @@ class TestMAP(VppTestCase): ip6_nh_address="4001::1", is_add=0) + if __name__ == '__main__': unittest.main(testRunner=VppTestRunner) |