make test: Add VCL iperf3 tests
[vpp.git] / test / test_vcl.py
1 #!/usr/bin/env python
2 """ Vpp VCL tests """
3
4 import unittest
5 import os
6 import subprocess
7 import signal
8 from framework import VppTestCase, VppTestRunner, running_extended_tests, \
9     Worker
10 from vpp_ip_route import VppIpTable, VppIpRoute, VppRoutePath
11
12
13 class VCLAppWorker(Worker):
14     """ VCL Test Application Worker """
15
16     def __init__(self, build_dir, appname, args, logger, env={}):
17         vcl_lib_dir = "%s/vpp/.libs" % build_dir
18         if "iperf" in appname:
19             app = appname
20             env.update({'LD_PRELOAD':
21                         "%s/libvcl_ldpreload.so.0.0.0" % vcl_lib_dir})
22         else:
23             app = "%s/%s" % (vcl_lib_dir, appname)
24             if not os.path.isfile(app):
25                 app = "%s/vpp/%s" % (build_dir, appname)
26                 env.update({'LD_PRELOAD':
27                             "%s/libvcl_ldpreload.so.0.0.0" % vcl_lib_dir})
28         self.args = [app] + args
29         super(VCLAppWorker, self).__init__(self.args, logger, env)
30
31
32 class VCLTestCase(VppTestCase):
33     """ VCL Test Class """
34
35     def __init__(self, methodName):
36         var = "VPP_TEST_BUILD_DIR"
37         self.build_dir = os.getenv(var, None)
38         if self.build_dir is None:
39             raise Exception("Environment variable `%s' not set" % var)
40         self.vppDebug = 'vpp_debug' in self.build_dir
41         self.server_addr = "127.0.0.1"
42         self.server_port = "22000"
43         self.server_args = [self.server_port]
44         self.timeout = 3
45         self.echo_phrase = "Hello, world! Jenny is a friend of mine."
46
47         super(VCLTestCase, self).__init__(methodName)
48
49     def cut_thru_setup(self):
50         self.vapi.session_enable_disable(is_enabled=1)
51
52     def cut_thru_tear_down(self):
53         self.vapi.session_enable_disable(is_enabled=0)
54
55     def cut_thru_test(self, server_app, server_args, client_app, client_args):
56         self.env = {'VCL_API_PREFIX': self.shm_prefix,
57                     'VCL_APP_SCOPE_LOCAL': "true"}
58
59         worker_server = VCLAppWorker(self.build_dir, server_app, server_args,
60                                      self.logger, self.env)
61         worker_server.start()
62         self.sleep(0.2)
63         worker_client = VCLAppWorker(self.build_dir, client_app, client_args,
64                                      self.logger, self.env)
65         worker_client.start()
66         worker_client.join(self.timeout)
67         try:
68             self.validateResults(worker_client, worker_server, self.timeout)
69         except Exception, error:
70             self.fail("Failed with %s" % error)
71
72     def thru_host_stack_setup(self):
73         self.vapi.session_enable_disable(is_enabled=1)
74         self.create_loopback_interfaces(range(2))
75
76         table_id = 0
77
78         for i in self.lo_interfaces:
79             i.admin_up()
80
81             if table_id != 0:
82                 tbl = VppIpTable(self, table_id)
83                 tbl.add_vpp_config()
84
85             i.set_table_ip4(table_id)
86             i.config_ip4()
87             table_id += 1
88
89         # Configure namespaces
90         self.vapi.app_namespace_add(namespace_id="0", secret=1234,
91                                     sw_if_index=self.loop0.sw_if_index)
92         self.vapi.app_namespace_add(namespace_id="1", secret=5678,
93                                     sw_if_index=self.loop1.sw_if_index)
94
95         # Add inter-table routes
96         ip_t01 = VppIpRoute(self, self.loop1.local_ip4, 32,
97                             [VppRoutePath("0.0.0.0",
98                                           0xffffffff,
99                                           nh_table_id=1)])
100         ip_t10 = VppIpRoute(self, self.loop0.local_ip4, 32,
101                             [VppRoutePath("0.0.0.0",
102                                           0xffffffff,
103                                           nh_table_id=0)], table_id=1)
104         ip_t01.add_vpp_config()
105         ip_t10.add_vpp_config()
106
107     def thru_host_stack_tear_down(self):
108         for i in self.lo_interfaces:
109             i.unconfig_ip4()
110             i.set_table_ip4(0)
111             i.admin_down()
112
113         self.vapi.session_enable_disable(is_enabled=0)
114
115     def thru_host_stack_test(self, server_app, server_args,
116                              client_app, client_args):
117         self.env = {'VCL_API_PREFIX': self.shm_prefix,
118                     'VCL_APP_SCOPE_GLOBAL': "true",
119                     'VCL_APP_NAMESPACE_ID': "0",
120                     'VCL_APP_NAMESPACE_SECRET': "1234"}
121
122         worker_server = VCLAppWorker(self.build_dir, server_app, server_args,
123                                      self.logger, self.env)
124         worker_server.start()
125         self.sleep(0.2)
126
127         self.env.update({'VCL_APP_NAMESPACE_ID': "1",
128                          'VCL_APP_NAMESPACE_SECRET': "5678"})
129         worker_client = VCLAppWorker(self.build_dir, client_app, client_args,
130                                      self.logger, self.env)
131         worker_client.start()
132         worker_client.join(self.timeout)
133
134         try:
135             self.validateResults(worker_client, worker_server, self.timeout)
136         except Exception, error:
137             self.fail("Failed with %s" % error)
138
139     def validateResults(self, worker_client, worker_server, timeout):
140         if os.path.isdir('/proc/{}'.format(worker_server.process.pid)):
141             self.logger.info("Killing server worker process (pid %d)" %
142                              worker_server.process.pid)
143             os.killpg(os.getpgid(worker_server.process.pid), signal.SIGTERM)
144             worker_server.join()
145         self.logger.info("Client worker result is `%s'" % worker_client.result)
146         error = False
147         if worker_client.result is None:
148             try:
149                 error = True
150                 self.logger.error(
151                     "Timeout: %ss! Killing client worker process (pid %d)" %
152                     (timeout, worker_client.process.pid))
153                 os.killpg(os.getpgid(worker_client.process.pid),
154                           signal.SIGTERM)
155                 worker_client.join()
156             except:
157                 self.logger.debug(
158                     "Couldn't kill client worker process")
159                 raise
160         if error:
161             raise Exception(
162                 "Timeout! Client worker did not finish in %ss" % timeout)
163         self.assert_equal(worker_client.result, 0, "Binary test return code")
164
165
166 class VCLCutThruTestCase(VCLTestCase):
167     """ VCL Cut Thru Tests """
168
169     def setUp(self):
170         super(VCLCutThruTestCase, self).setUp()
171
172         self.cut_thru_setup()
173         self.client_echo_test_args = [self.server_addr, self.server_port,
174                                       "-E", self.echo_phrase, "-X"]
175         self.client_iperf3_timeout = 20
176         self.client_iperf3_args = ["-V4d", "-c", self.server_addr]
177         self.server_iperf3_args = ["-V4d", "-s"]
178         self.client_uni_dir_nsock_timeout = 60
179         self.client_uni_dir_nsock_test_args = [self.server_addr,
180                                                self.server_port,
181                                                "-I", "5", "-U", "-X"]
182         self.client_bi_dir_nsock_timeout = 120
183         self.client_bi_dir_nsock_test_args = [self.server_addr,
184                                               self.server_port,
185                                               "-I", "2", "-B", "-X"]
186
187     def tearDown(self):
188         self.cut_thru_tear_down()
189
190         super(VCLCutThruTestCase, self).tearDown()
191
192     def test_ldp_cut_thru_echo(self):
193         """ run LDP cut thru echo test """
194
195         self.cut_thru_test("sock_test_server", self.server_args,
196                            "sock_test_client", self.client_echo_test_args)
197
198     def test_ldp_cut_thru_iperf3(self):
199         """ run LDP cut thru iperf3 test """
200
201         try:
202             subprocess.check_output(['iperf3', '-v'])
203         except:
204             self.logger.error("WARNING: 'iperf3' is not installed,")
205             self.logger.error("         'test_ldp_cut_thru_iperf3' not run!")
206             return
207
208         self.timeout = self.client_iperf3_timeout
209         self.cut_thru_test("iperf3", self.server_iperf3_args,
210                            "iperf3", self.client_iperf3_args)
211
212     @unittest.skipUnless(running_extended_tests(), "part of extended tests")
213     def test_ldp_cut_thru_uni_dir_nsock(self):
214         """ run LDP cut thru uni-directional (multiple sockets) test """
215
216         self.timeout = self.client_uni_dir_nsock_timeout
217         self.cut_thru_test("sock_test_server", self.server_args,
218                            "sock_test_client",
219                            self.client_uni_dir_nsock_test_args)
220
221     @unittest.skipUnless(running_extended_tests(), "part of extended tests")
222     def test_ldp_cut_thru_bi_dir_nsock(self):
223         """ run LDP cut thru bi-directional (multiple sockets) test """
224
225         self.timeout = self.client_bi_dir_nsock_timeout
226         self.cut_thru_test("sock_test_server", self.server_args,
227                            "sock_test_client",
228                            self.client_bi_dir_nsock_test_args)
229
230     def test_vcl_cut_thru_echo(self):
231         """ run VCL cut thru echo test """
232
233         self.cut_thru_test("vcl_test_server", self.server_args,
234                            "vcl_test_client", self.client_echo_test_args)
235
236     @unittest.skipUnless(running_extended_tests(), "part of extended tests")
237     def test_vcl_cut_thru_uni_dir_nsock(self):
238         """ run VCL cut thru uni-directional (multiple sockets) test """
239
240         self.timeout = self.client_uni_dir_nsock_timeout
241         self.cut_thru_test("vcl_test_server", self.server_args,
242                            "vcl_test_client",
243                            self.client_uni_dir_nsock_test_args)
244
245     @unittest.skipUnless(running_extended_tests(), "part of extended tests")
246     def test_vcl_cut_thru_bi_dir_nsock(self):
247         """ run VCL cut thru bi-directional (multiple sockets) test """
248
249         self.timeout = self.client_bi_dir_nsock_timeout
250         self.cut_thru_test("vcl_test_server", self.server_args,
251                            "vcl_test_client",
252                            self.client_bi_dir_nsock_test_args)
253
254
255 class VCLThruHostStackTestCase(VCLTestCase):
256     """ VCL Thru Host Stack Tests """
257
258     def setUp(self):
259         super(VCLThruHostStackTestCase, self).setUp()
260
261         self.thru_host_stack_setup()
262         self.client_echo_test_args = [self.loop0.local_ip4,
263                                       self.server_port,
264                                       "-E", self.echo_phrase, "-X"]
265
266     def tearDown(self):
267         self.thru_host_stack_tear_down()
268
269         super(VCLThruHostStackTestCase, self).tearDown()
270
271     def test_ldp_thru_host_stack_echo(self):
272         """ run LDP thru host stack echo test """
273
274         self.thru_host_stack_test("sock_test_server", self.server_args,
275                                   "sock_test_client",
276                                   self.client_echo_test_args)
277         # TBD: Remove these when VPP thru host teardown config bug is fixed.
278         self.thru_host_stack_test("vcl_test_server", self.server_args,
279                                   "vcl_test_client",
280                                   self.client_echo_test_args)
281
282     def test_vcl_thru_host_stack_echo(self):
283         """ run VCL thru host stack echo test """
284
285         # TBD: Enable this when VPP  thru host teardown config bug is fixed.
286         # self.thru_host_stack_test("vcl_test_server", self.server_args,
287         #                           "vcl_test_client",
288         #                           self.client_echo_test_args)
289
290     # TBD: Remove VCLThruHostStackExtended*TestCase classes and move
291     #      tests here when VPP  thru host teardown/setup config bug
292     #      is fixed.
293
294
295 class VCLThruHostStackExtendedATestCase(VCLTestCase):
296     """ VCL Thru Host Stack Extended Tests """
297
298     def setUp(self):
299         super(VCLThruHostStackExtendedATestCase, self).setUp()
300
301         self.thru_host_stack_setup()
302         if self.vppDebug:
303             self.client_bi_dir_nsock_timeout = 120
304         else:
305             self.client_bi_dir_nsock_timeout = 60
306         self.client_bi_dir_nsock_test_args = [self.loop0.local_ip4,
307                                               self.server_port,
308                                               "-I", "2", "-B", "-X"]
309
310     def tearDown(self):
311         self.thru_host_stack_tear_down()
312
313         super(VCLThruHostStackExtendedATestCase, self).tearDown()
314
315     @unittest.skipUnless(running_extended_tests(), "part of extended tests")
316     def test_vcl_thru_host_stack_bi_dir_nsock(self):
317         """ run VCL thru host stack bi-directional (multiple sockets) test """
318
319         self.timeout = self.client_bi_dir_nsock_timeout
320         self.thru_host_stack_test("vcl_test_server", self.server_args,
321                                   "vcl_test_client",
322                                   self.client_bi_dir_nsock_test_args)
323
324
325 class VCLThruHostStackExtendedBTestCase(VCLTestCase):
326     """ VCL Thru Host Stack Extended Tests """
327
328     def setUp(self):
329         super(VCLThruHostStackExtendedBTestCase, self).setUp()
330
331         self.thru_host_stack_setup()
332         if self.vppDebug:
333             self.client_bi_dir_nsock_timeout = 120
334         else:
335             self.client_bi_dir_nsock_timeout = 60
336         self.client_bi_dir_nsock_test_args = [self.loop0.local_ip4,
337                                               self.server_port,
338                                               "-I", "2", "-B", "-X"]
339
340     def tearDown(self):
341         self.thru_host_stack_tear_down()
342
343         super(VCLThruHostStackExtendedBTestCase, self).tearDown()
344
345     @unittest.skipUnless(running_extended_tests(), "part of extended tests")
346     def test_ldp_thru_host_stack_bi_dir_nsock(self):
347         """ run LDP thru host stack bi-directional (multiple sockets) test """
348
349         self.timeout = self.client_bi_dir_nsock_timeout
350         self.thru_host_stack_test("sock_test_server", self.server_args,
351                                   "sock_test_client",
352                                   self.client_bi_dir_nsock_test_args)
353
354
355 class VCLThruHostStackExtendedCTestCase(VCLTestCase):
356     """ VCL Thru Host Stack Extended Tests """
357
358     def setUp(self):
359         super(VCLThruHostStackExtendedCTestCase, self).setUp()
360
361         self.thru_host_stack_setup()
362         if self.vppDebug:
363             self.client_uni_dir_nsock_timeout = 120
364             self.numSockets = "2"
365         else:
366             self.client_uni_dir_nsock_timeout = 120
367             self.numSockets = "5"
368
369         self.client_uni_dir_nsock_test_args = [self.loop0.local_ip4,
370                                                self.server_port,
371                                                "-I", self.numSockets,
372                                                "-U", "-X"]
373
374     def tearDown(self):
375         self.thru_host_stack_tear_down()
376
377         super(VCLThruHostStackExtendedCTestCase, self).tearDown()
378
379     @unittest.skipUnless(running_extended_tests(), "part of extended tests")
380     def test_ldp_thru_host_stack_uni_dir_nsock(self):
381         """ run LDP thru host stack uni-directional (multiple sockets) test """
382
383         self.timeout = self.client_uni_dir_nsock_timeout
384         self.thru_host_stack_test("sock_test_server", self.server_args,
385                                   "sock_test_client",
386                                   self.client_uni_dir_nsock_test_args)
387
388
389 class VCLThruHostStackExtendedDTestCase(VCLTestCase):
390     """ VCL Thru Host Stack Extended Tests """
391
392     def setUp(self):
393         super(VCLThruHostStackExtendedDTestCase, self).setUp()
394
395         self.thru_host_stack_setup()
396         if self.vppDebug:
397             self.client_uni_dir_nsock_timeout = 120
398             self.numSockets = "2"
399         else:
400             self.client_uni_dir_nsock_timeout = 120
401             self.numSockets = "5"
402
403         self.client_uni_dir_nsock_test_args = [self.loop0.local_ip4,
404                                                self.server_port,
405                                                "-I", self.numSockets,
406                                                "-U", "-X"]
407
408     def tearDown(self):
409         self.thru_host_stack_tear_down()
410
411         super(VCLThruHostStackExtendedDTestCase, self).tearDown()
412
413     @unittest.skipUnless(running_extended_tests(), "part of extended tests")
414     def test_vcl_thru_host_stack_uni_dir_nsock(self):
415         """ run VCL thru host stack uni-directional (multiple sockets) test """
416
417         self.timeout = self.client_uni_dir_nsock_timeout
418         self.thru_host_stack_test("vcl_test_server", self.server_args,
419                                   "vcl_test_client",
420                                   self.client_uni_dir_nsock_test_args)
421
422
423 class VCLThruHostStackIperfTestCase(VCLTestCase):
424     """ VCL Thru Host Stack Iperf Tests """
425
426     def setUp(self):
427         super(VCLThruHostStackIperfTestCase, self).setUp()
428
429         self.thru_host_stack_setup()
430         self.client_iperf3_timeout = 20
431         self.client_iperf3_args = ["-V4d", "-c", self.loop0.local_ip4]
432         self.server_iperf3_args = ["-V4d", "-s"]
433
434     def tearDown(self):
435         self.thru_host_stack_tear_down()
436
437         super(VCLThruHostStackIperfTestCase, self).tearDown()
438
439     def test_ldp_thru_host_stack_iperf3(self):
440         """ run LDP thru host stack iperf3 test """
441
442         try:
443             subprocess.check_output(['iperf3', '-v'])
444         except:
445             self.logger.error("WARNING: 'iperf3' is not installed,")
446             self.logger.error(
447                 "         'test_ldp_thru_host_stack_iperf3' not run!")
448             return
449
450         self.timeout = self.client_iperf3_timeout
451         self.thru_host_stack_test("iperf3", self.server_iperf3_args,
452                                   "iperf3", self.client_iperf3_args)
453
454
455 if __name__ == '__main__':
456     unittest.main(testRunner=VppTestRunner)