MFIB: coverity fixes
[vpp.git] / test / vpp_config.py
1 # Copyright 2018 Vinci Consulting Corp. All Rights Reserved.
2 #
3 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
4 #    not use this file except in compliance with the License. You may obtain
5 #    a copy of the License at
6 #
7 #         http://www.apache.org/licenses/LICENSE-2.0
8 #
9 #    Unless required by applicable law or agreed to in writing, software
10 #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 #    License for the specific language governing permissions and limitations
13 #    under the License.
14
15 import shlex
16 import unittest
17
18
19 class VppConfig(object):
20     stanzas = ['unix', 'api-trace', 'api-segment',
21                'socksvr', 'cpu', 'statseg', 'dpdk', 'plugins', 'tuntap',
22                'punt']
23     kw = {'unix': ['interactive', 'nodaemon', 'log', 'full-coredump',
24                    'coredump-size', 'cli-listen', 'runtime-dir', 'gid'],
25           'acl-plugin': ['connection hash buckets', 'connection hash memory',
26                          'connection count max', 'main heap size',
27                          'hash lookup heap size', 'hash lookup hash buckets',
28                          'hash lookup hash memory', 'use tuple merge',
29                          'tuple merge split threshold', 'reclassify sessions'],
30           'api-queue': ['len', 'length'],
31           'api-trace': ['on', 'enable, ''nitems', 'save-api-table'],
32           'api-segment': ['prefix', 'gid'],
33           'cj': ['on', 'records'],
34           'cpu': ['main-core', 'corelist-workers', 'skip-cores',
35                   'workers', 'scheduler-policy', 'scheduler-priority'],
36           'dns': ['max-cache-size', 'max-ttl'],
37           'dpdk': ['dev', 'vdev', 'name', 'hqos', 'rss',
38                    'no-multi-seg',
39                    'num-mbufs', 'num-rx-queues', 'num-tx-queues',
40                    'num-rx-desc', 'num-tx-desc',
41                    'socket-mem', 'no-tx-checksum-offload', 'uio-driver',
42                    'vlan-strip-offload', 'workers'],
43           # currently don't support dynamic keys
44           # 'heapsize': [],
45           'l2learn': ['limit'],
46           'l2tp': ['lookup-v6-src', 'lookup-v6-dst',
47                    'lookup-session-id'],
48           'nat': ['connection tracking', 'deterministic', 'dslite ce',
49                   'endpoint-dependent', 'inside VRF id',
50                   'max translations per user',
51                   'nat64 bib hash bucket', 'nat64 bib hash memory',
52                   'nat64 st hash buckets',
53                   'outside ip6 VRF id', 'outside VRF id', 'out2in dpo'
54                   'static mapping only',
55                   'translation hash buckets',
56                   'translation hash memory',
57                   'user hash buckets', 'user hash memory',
58                   ],
59           'mactime': ['lookup-table-buckets', 'lookup-table-memory',
60                       'timezone_offset'],
61           'mc': ['interface', 'no-delay', 'no-validate', 'max-delay',
62                  'min-delay', 'n-bytes', 'n-packets',
63                  'max-n-bytes',
64                  'min-n-bytes',
65                  'seed', 'window', 'verbose', ],
66           'oam': ['interval', 'misses-allowed'],
67           'plugins': ['path', 'plugin'],
68           'punt': ['socket'],
69           'session': ['event-queue-length', 'preallocated-sessions',
70                       'v4-session-table-buckets', 'v4-halfopen-table-buckets',
71                       'v6-session-table-buckets', 'v6-halfopen-table-buckets',
72                       'v6-halfopen-table-buckets'
73                       ],
74           'socksvr': ['default', 'socket-name'],
75           'statseg': ['socket-name'],
76           'tapcli': ['disable', 'mtu'],
77           'tcp': ['buffer-fail-fraction', 'cc-algo', 'max-rx-fifo',
78                   'no-tx-pacing', 'preallocated-connections',
79                   'preallocated-half-open-connections',
80                   ],
81           'tuntap': ['name', 'mtu', 'enable', 'disable',
82                      'ether', 'ethernet',
83                      'have-normal', 'have-normal-interface'
84                      ],
85           'vhost-user': ['coalesce-frames', 'coalesce-time',
86                          'dont-dump-memory']
87
88
89           }
90     default_values = {'unix': {'interactive': None,
91                                }
92                       }
93
94     def __init__(self):
95         self.values = type(self).default_values
96         self.plugins = []
97
98     def add(self, stanza, key, val):
99         if stanza not in type(self).stanzas:
100             raise ValueError("stanza '%s' must be in %s" %
101                              (stanza, type(self).stanzas))
102         if key not in type(self).kw[stanza]:
103             raise ValueError("key '%s' must be in %s" %
104                              (key, type(self).kw[stanza]))
105         self.values[stanza][key] = val
106
107     def add_plugin(self, key, val):
108         self.plugins.append((key, val,))
109
110     def __str__(self):
111         result = ''
112         for stanza in type(self).stanzas:
113             try:
114                 if self.values[stanza]:
115                     result = '%s\n%s {' % (result, stanza)
116                     for key in type(self).kw[stanza]:
117                         try:
118                             if key in self.values[stanza]:
119                                 result = '%s\n    %s %s' % (
120                                     result, key,
121                                     self.values[stanza][key]
122                                     if self.values[stanza][key] is not
123                                     None else '')
124                         except KeyError:
125                             # no key: nothing to do
126                             pass
127                         if stanza == 'plugins' and key == 'plugin':
128                             for plugin, val in self.plugins:
129                                 result = '%s\n    plugin %s { % s }' % (
130                                     result, plugin,
131                                     val if val is not None else '')
132                     result = '%s\n}\n' % result
133             except KeyError:
134                 # no stanza not in self.values: nothing to do
135                 pass
136         return result
137
138     def shlex(self):
139         return shlex.split(str(self))
140
141
142 class MinimalVppConfig(VppConfig):
143     default_values = {'unix': {'interactive': None,
144                                'cli-listen': 'run/vpp/cli.sock',
145                                'gid': 1000
146                                }
147                       }
148
149
150 class VppTestCaseVppConfig(VppConfig):
151     default_values = {'unix': {'nodaemon': None,
152                                'full-coredump': None,
153                                },
154                       'acl-plugin': {},
155                       'api-queue': {},
156                       'api-trace': {'on': None},
157                       'api-segment': {},
158                       'cj': {},
159                       'cpu': {},
160                       'dns': {},
161                       'dpdk': {},
162                       # currently don't support dynamic keys
163                       # 'heapsize': {},
164                       'l2learn': {},
165                       'l2tp': {},
166                       'mactime': {},
167                       'mc': {},
168                       'nat': {},
169                       'oam': {},
170                       'plugins': {},
171                       'punt': {},
172                       'session': {},
173                       'socksvr': {'default': None},
174                       'statseg': {},
175                       'tapcli': {},
176                       'tcp': {},
177                       'tuntap': {},
178                       'vhost-user': {},
179                       }
180
181
182 class TestVppConfig(unittest.TestCase):
183
184     def setUp(self):
185         self.config = VppTestCaseVppConfig()
186
187     def test_unix(self):
188         size = None
189         tempdir = '/tmp'
190
191         # reset default values for this test.
192         self.config.default_values['unix'] = {}
193         self.config.add('unix', 'coredump-size', size
194                         if size is not None else 'unlimited')
195         self.assertIn('unix {\n    coredump-size unlimited\n}\n',
196                       str(self.config))
197
198         self.config.add('unix', 'runtime-dir', tempdir)
199         self.assertIn('runtime-dir /tmp', str(self.config))
200
201     def test_api_segment(self):
202         shm_prefix = '/dev/shm'
203         self.config.add('api-segment', 'prefix', shm_prefix)
204         self.assertIn('api-segment {\n    prefix /dev/shm\n}\n',
205                       str(self.config))
206
207     def test_cpu(self):
208         luc = 0
209         self.config.add('cpu', 'main-core', str(luc))
210         self.assertIn('cpu {\n    main-core 0\n}\n', str(self.config))
211
212     def test_statseg(self):
213         stats_sock = '/stats.sock'
214         self.config.add('statseg', 'socket-name', stats_sock)
215         self.assertIn('statseg {\n    socket-name /stats.sock\n}\n',
216                       str(self.config))
217
218     def test_plugin(self):
219         plugin_path = '/foo'
220         self.config.add('plugins', 'path', plugin_path)
221         self.assertIn('plugins {\n    path /foo\n}\n',
222                       str(self.config))
223
224         self.config.add_plugin('dpdk_plugin.so', 'disable')
225         self.config.add_plugin('unittest_plugin.so', 'enable')
226         self.assertIn('plugin dpdk_plugin.so { disable }\n',
227                       str(self.config))
228         self.assertIn('plugin unittest_plugin.so { enable }\n',
229                       str(self.config))
230
231
232 if __name__ == '__main__':
233     unittest.main()