4 from vppapigen import VPPAPI, Option, ParseError, Union, foldup_crcs, \
10 # - test parsing of options, typedefs, enums, defines
11 # - test JSON, C output
14 class TestVersion(unittest.TestCase):
19 def test_version(self):
20 version_string = 'option version = "1.0.0";'
21 r = self.parser.parse_string(version_string)
22 self.assertTrue(isinstance(r[0], Option))
25 class TestUnion(unittest.TestCase):
37 r = self.parser.parse_string(test_string)
38 self.assertTrue(isinstance(r[0], Union))
40 def test_union_vla(self):
46 autoreply define foo {
47 vl_api_foo_union_vla_t v;
50 r = self.parser.parse_string(test_string)
51 self.assertTrue(isinstance(r[0], Union))
52 self.assertTrue(r[0].vla)
53 s = self.parser.process(r)
56 union foo_union_vla2 {
61 autoreply define foo2 {
62 vl_api_foo_union_vla2_t v;
65 self.assertRaises(ValueError, self.parser.parse_string, test_string2)
68 union foo_union_vla3 {
72 autoreply define foo3 {
73 vl_api_foo_union_vla3_t v;
77 self.assertRaises(ValueError, self.parser.parse_string, test_string3)
80 class TestTypedef(unittest.TestCase):
85 def test_duplicatetype(self):
87 typedef foo1 { u8 dummy; };
88 typedef foo1 { u8 dummy; };
90 self.assertRaises(KeyError, self.parser.parse_string, test_string)
93 class TestDefine(unittest.TestCase):
98 def test_unknowntype(self):
99 test_string = 'define foo { foobar foo;};'
100 with self.assertRaises(ParseError) as ctx:
101 self.parser.parse_string(test_string)
102 self.assertIn('Undefined type: foobar', str(ctx.exception))
104 test_string = 'define { u8 foo;};'
105 with self.assertRaises(ParseError) as ctx:
106 self.parser.parse_string(test_string)
108 def test_flags(self):
110 manual_print dont_trace manual_endian define foo { u8 foo; };
111 define foo_reply {u32 context; i32 retval; };
113 r = self.parser.parse_string(test_string)
114 self.assertIsNotNone(r)
115 s = self.parser.process(r)
116 self.assertIsNotNone(s)
117 for d in s['Define']:
119 self.assertTrue(d.dont_trace)
120 self.assertTrue(d.manual_endian)
121 self.assertTrue(d.manual_print)
122 self.assertFalse(d.autoreply)
125 nonexisting_flag define foo { u8 foo; };
127 with self.assertRaises(ParseError):
128 self.parser.parse_string(test_string)
130 def test_options(self):
132 define foo { option deprecated; u8 foo; };
133 define foo_reply {u32 context; i32 retval; };
135 r = self.parser.parse_string(test_string)
136 self.assertIsNotNone(r)
137 s = self.parser.process(r)
138 self.assertIsNotNone(s)
141 class TestService(unittest.TestCase):
144 cls.parser = VPPAPI()
146 def test_service(self):
148 autoreply define show_version { u8 foo;};
149 service { rpc show_version returns show_version_reply; };
151 r = self.parser.parse_string(test_string)
152 s = self.parser.process(r)
153 self.assertEqual(s['Service'][0].caller, 'show_version')
154 self.assertEqual(s['Service'][0].reply, 'show_version_reply')
157 def get_crc(apistring, name):
158 vppapigen.global_types = {}
159 parser = vppapigen.VPPAPI()
160 r = parser.parse_string(apistring)
161 s = parser.process(r)
162 foldup_crcs(s['Define'])
163 d = [f for f in s['Define'] if f.name == name]
167 class TestCRC(unittest.TestCase):
170 typedef list { u8 foo; };
171 autoreply define foo { u8 foo; vl_api_list_t l;};
173 crc = get_crc(test_string, 'foo')
175 # modify underlying type
177 typedef list { u8 foo2; };
178 autoreply define foo { u8 foo; vl_api_list_t l;};
180 crc2 = get_crc(test_string, 'foo')
181 self.assertNotEqual(crc, crc2)
183 # two user-defined types
185 typedef address { u8 foo2; };
186 typedef list { u8 foo2; vl_api_address_t add; };
187 autoreply define foo { u8 foo; vl_api_list_t l;};
189 crc3 = get_crc(test_string, 'foo')
192 typedef address { u8 foo3; };
193 typedef list { u8 foo2; vl_api_address_t add; };
194 autoreply define foo { u8 foo; vl_api_list_t l;};
196 crc4 = get_crc(test_string, 'foo')
197 self.assertNotEqual(crc3, crc4)
200 typedef address { u8 foo3; };
201 typedef list { u8 foo2; vl_api_address_t add; u8 foo3; };
202 autoreply define foo { u8 foo; vl_api_list_t l;};
204 crc5 = get_crc(test_string, 'foo')
205 self.assertNotEqual(crc4, crc5)
212 typedef srv6_sid_list
217 vl_api_ip6_address_t sids[16];
219 autoreply define sr_policy_add
223 vl_api_ip6_address_t bsid_addr;
228 vl_api_srv6_sid_list_t sids;
232 crc = get_crc(test_string, 'sr_policy_add')
239 typedef srv6_sid_list
243 vl_api_ip6_address_t sids[16];
245 autoreply define sr_policy_add
249 vl_api_ip6_address_t bsid_addr;
254 vl_api_srv6_sid_list_t sids;
257 crc2 = get_crc(test_string, 'sr_policy_add')
259 self.assertNotEqual(crc, crc2)
262 class TestEnum(unittest.TestCase):
266 cls.parser = VPPAPI()
268 def test_enum_as_enum(self):
270 enum tunnel_mode : u8
272 /** point-to-point */
273 TUNNEL_API_MODE_P2P = 0,
278 r = self.parser.parse_string(test_string)
279 self.assertIsNotNone(r)
280 s = self.parser.process(r)
283 self.assertEqual(o.name, "tunnel_mode")
288 def test_enumflag_as_enum(self):
291 VIRTIO_API_FLAG_GSO = 1, /* enable gso on the interface */
292 VIRTIO_API_FLAG_CSUM_OFFLOAD = 2, /* enable checksum offload without gso on the interface */
293 VIRTIO_API_FLAG_GRO_COALESCE = 4, /* enable packet coalescing on tx side, provided gso enabled */
294 VIRTIO_API_FLAG_PACKED = 8, /* enable packed ring support, provided it is available from backend */
295 VIRTIO_API_FLAG_IN_ORDER = 16, /* enable in order support, provided it is available from backend */
296 VIRTIO_API_FLAG_BUFFERING = 32 [backwards_compatible], /* enable buffering to handle backend jitter/delays */
298 r = self.parser.parse_string(test_string)
299 self.assertIsNotNone(r)
300 s = self.parser.process(r)
303 self.assertEqual(o.name, "virtio_flags")
309 class TestEnumFlag(unittest.TestCase):
313 cls.parser = VPPAPI()
315 def test_enum_as_enumflag(self):
317 enumflag tunnel_mode_ef : u8
319 /** point-to-point */
320 TUNNEL_API_MODE_P2P = 0,
326 with self.assertRaises(TypeError) as ctx:
327 r = self.parser.parse_string(test_string)
329 self.assertTrue(str(ctx.exception).startswith(
330 'tunnel_mode_ef is not a flag enum.'))
332 def test_enumflag_as_enumflag(self):
334 enumflag virtio_flags_ef {
335 VIRTIO_API_FLAG_GSO = 1, /* enable gso on the interface */
336 VIRTIO_API_FLAG_CSUM_OFFLOAD = 2, /* enable checksum offload without gso on the interface */
337 VIRTIO_API_FLAG_GRO_COALESCE = 4, /* enable packet coalescing on tx side, provided gso enabled */
338 VIRTIO_API_FLAG_PACKED = 8, /* enable packed ring support, provided it is available from backend */
339 VIRTIO_API_FLAG_IN_ORDER = 16, /* enable in order support, provided it is available from backend */
340 VIRTIO_API_FLAG_BUFFERING = 32 [backwards_compatible], /* enable buffering to handle backend jitter/delays */
342 r = self.parser.parse_string(test_string)
343 self.assertIsNotNone(r)
344 s = self.parser.process(r)
346 if o.type == 'EnumFlag':
347 self.assertEqual(o.name, "virtio_flags_ef")
353 if __name__ == '__main__':
354 unittest.main(verbosity=2)