4 from vppapigen import VPPAPI, Option, ParseError, Union, foldup_crcs, global_types
9 # - test parsing of options, typedefs, enums, defines
10 # - test JSON, C output
13 class TestVersion(unittest.TestCase):
18 def test_version(self):
19 version_string = 'option version = "1.0.0";'
20 r = self.parser.parse_string(version_string)
21 self.assertTrue(isinstance(r[0], Option))
24 class TestUnion(unittest.TestCase):
36 r = self.parser.parse_string(test_string)
37 self.assertTrue(isinstance(r[0], Union))
39 def test_union_vla(self):
45 autoreply define foo {
46 vl_api_foo_union_vla_t v;
49 r = self.parser.parse_string(test_string)
50 self.assertTrue(isinstance(r[0], Union))
51 self.assertTrue(r[0].vla)
52 s = self.parser.process(r)
55 union foo_union_vla2 {
60 autoreply define foo2 {
61 vl_api_foo_union_vla2_t v;
64 self.assertRaises(ValueError, self.parser.parse_string, test_string2)
67 union foo_union_vla3 {
71 autoreply define foo3 {
72 vl_api_foo_union_vla3_t v;
76 self.assertRaises(ValueError, self.parser.parse_string, test_string3)
79 class TestTypedef(unittest.TestCase):
84 def test_duplicatetype(self):
86 typedef foo1 { u8 dummy; };
87 typedef foo1 { u8 dummy; };
89 self.assertRaises(KeyError, self.parser.parse_string, test_string)
92 class TestDefine(unittest.TestCase):
97 def test_unknowntype(self):
98 test_string = "define foo { foobar foo;};"
99 with self.assertRaises(ParseError) as ctx:
100 self.parser.parse_string(test_string)
101 self.assertIn("Undefined type: foobar", str(ctx.exception))
103 test_string = "define { u8 foo;};"
104 with self.assertRaises(ParseError) as ctx:
105 self.parser.parse_string(test_string)
107 def test_flags(self):
109 manual_print dont_trace manual_endian define foo { u8 foo; };
110 define foo_reply {u32 context; i32 retval; };
112 r = self.parser.parse_string(test_string)
113 self.assertIsNotNone(r)
114 s = self.parser.process(r)
115 self.assertIsNotNone(s)
116 for d in s["Define"]:
118 self.assertTrue(d.dont_trace)
119 self.assertTrue(d.manual_endian)
120 self.assertTrue(d.manual_print)
121 self.assertFalse(d.autoreply)
124 nonexisting_flag define foo { u8 foo; };
126 with self.assertRaises(ParseError):
127 self.parser.parse_string(test_string)
129 def test_options(self):
131 define foo { option deprecated; u8 foo; };
132 define foo_reply {u32 context; i32 retval; };
134 r = self.parser.parse_string(test_string)
135 self.assertIsNotNone(r)
136 s = self.parser.process(r)
137 self.assertIsNotNone(s)
140 class TestService(unittest.TestCase):
143 cls.parser = VPPAPI()
145 def test_service(self):
147 autoreply define show_version { u8 foo;};
148 service { rpc show_version returns show_version_reply; };
150 r = self.parser.parse_string(test_string)
151 s = self.parser.process(r)
152 self.assertEqual(s["Service"][0].caller, "show_version")
153 self.assertEqual(s["Service"][0].reply, "show_version_reply")
156 def get_crc(apistring, name):
157 vppapigen.global_types = {}
158 parser = vppapigen.VPPAPI()
159 r = parser.parse_string(apistring)
160 s = parser.process(r)
161 foldup_crcs(s["Define"])
162 d = [f for f in s["Define"] if f.name == name]
166 class TestCRC(unittest.TestCase):
169 typedef list { u8 foo; };
170 autoreply define foo { u8 foo; vl_api_list_t l;};
172 crc = get_crc(test_string, "foo")
174 # modify underlying type
176 typedef list { u8 foo2; };
177 autoreply define foo { u8 foo; vl_api_list_t l;};
179 crc2 = get_crc(test_string, "foo")
180 self.assertNotEqual(crc, crc2)
182 # two user-defined types
184 typedef address { u8 foo2; };
185 typedef list { u8 foo2; vl_api_address_t add; };
186 autoreply define foo { u8 foo; vl_api_list_t l;};
188 crc3 = get_crc(test_string, "foo")
191 typedef address { u8 foo3; };
192 typedef list { u8 foo2; vl_api_address_t add; };
193 autoreply define foo { u8 foo; vl_api_list_t l;};
195 crc4 = get_crc(test_string, "foo")
196 self.assertNotEqual(crc3, crc4)
199 typedef address { u8 foo3; };
200 typedef list { u8 foo2; vl_api_address_t add; u8 foo3; };
201 autoreply define foo { u8 foo; vl_api_list_t l;};
203 crc5 = get_crc(test_string, "foo")
204 self.assertNotEqual(crc4, crc5)
211 typedef srv6_sid_list
216 vl_api_ip6_address_t sids[16];
218 autoreply define sr_policy_add
222 vl_api_ip6_address_t bsid_addr;
227 vl_api_srv6_sid_list_t sids;
231 crc = get_crc(test_string, "sr_policy_add")
238 typedef srv6_sid_list
242 vl_api_ip6_address_t sids[16];
244 autoreply define sr_policy_add
248 vl_api_ip6_address_t bsid_addr;
253 vl_api_srv6_sid_list_t sids;
256 crc2 = get_crc(test_string, "sr_policy_add")
258 self.assertNotEqual(crc, crc2)
261 class TestEnum(unittest.TestCase):
264 cls.parser = VPPAPI()
266 def test_enum_as_enum(self):
268 enum tunnel_mode : u8
270 /** point-to-point */
271 TUNNEL_API_MODE_P2P = 0,
276 r = self.parser.parse_string(test_string)
277 self.assertIsNotNone(r)
278 s = self.parser.process(r)
281 self.assertEqual(o.name, "tunnel_mode")
286 def test_enumflag_as_enum(self):
289 VIRTIO_API_FLAG_GSO = 1, /* enable gso on the interface */
290 VIRTIO_API_FLAG_CSUM_OFFLOAD = 2, /* enable checksum offload without gso on the interface */
291 VIRTIO_API_FLAG_GRO_COALESCE = 4, /* enable packet coalescing on tx side, provided gso enabled */
292 VIRTIO_API_FLAG_PACKED = 8, /* enable packed ring support, provided it is available from backend */
293 VIRTIO_API_FLAG_IN_ORDER = 16, /* enable in order support, provided it is available from backend */
294 VIRTIO_API_FLAG_BUFFERING = 32 [backwards_compatible], /* enable buffering to handle backend jitter/delays */
296 r = self.parser.parse_string(test_string)
297 self.assertIsNotNone(r)
298 s = self.parser.process(r)
301 self.assertEqual(o.name, "virtio_flags")
307 class TestEnumFlag(unittest.TestCase):
310 cls.parser = VPPAPI()
312 def test_enum_as_enumflag(self):
314 enumflag tunnel_mode_ef : u8
316 /** point-to-point */
317 TUNNEL_API_MODE_P2P = 0,
323 with self.assertRaises(TypeError) as ctx:
324 r = self.parser.parse_string(test_string)
327 str(ctx.exception).startswith("tunnel_mode_ef is not a flag enum.")
330 def test_enumflag_as_enumflag(self):
332 enumflag virtio_flags_ef {
333 VIRTIO_API_FLAG_GSO = 1, /* enable gso on the interface */
334 VIRTIO_API_FLAG_CSUM_OFFLOAD = 2, /* enable checksum offload without gso on the interface */
335 VIRTIO_API_FLAG_GRO_COALESCE = 4, /* enable packet coalescing on tx side, provided gso enabled */
336 VIRTIO_API_FLAG_PACKED = 8, /* enable packed ring support, provided it is available from backend */
337 VIRTIO_API_FLAG_IN_ORDER = 16, /* enable in order support, provided it is available from backend */
338 VIRTIO_API_FLAG_BUFFERING = 32 [backwards_compatible], /* enable buffering to handle backend jitter/delays */
340 r = self.parser.parse_string(test_string)
341 self.assertIsNotNone(r)
342 s = self.parser.process(r)
344 if o.type == "EnumFlag":
345 self.assertEqual(o.name, "virtio_flags_ef")
351 if __name__ == "__main__":
352 unittest.main(verbosity=2)