aboutsummaryrefslogtreecommitdiffstats
path: root/test/vpp_config.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/vpp_config.py')
-rw-r--r--test/vpp_config.py233
1 files changed, 233 insertions, 0 deletions
diff --git a/test/vpp_config.py b/test/vpp_config.py
new file mode 100644
index 00000000000..03cddf80ade
--- /dev/null
+++ b/test/vpp_config.py
@@ -0,0 +1,233 @@
+# Copyright 2018 Vinci Consulting Corp. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import shlex
+import unittest
+
+
+class VppConfig(object):
+ stanzas = ['unix', 'api-trace', 'api-segment',
+ 'socksvr', 'cpu', 'statseg', 'dpdk', 'plugins', 'tuntap',
+ 'punt']
+ kw = {'unix': ['interactive', 'nodaemon', 'log', 'full-coredump',
+ 'coredump-size', 'cli-listen', 'runtime-dir', 'gid'],
+ 'acl-plugin': ['connection hash buckets', 'connection hash memory',
+ 'connection count max', 'main heap size',
+ 'hash lookup heap size', 'hash lookup hash buckets',
+ 'hash lookup hash memory', 'use tuple merge',
+ 'tuple merge split threshold', 'reclassify sessions'],
+ 'api-queue': ['len', 'length'],
+ 'api-trace': ['on', 'enable, ''nitems', 'save-api-table'],
+ 'api-segment': ['prefix', 'gid'],
+ 'cj': ['on', 'records'],
+ 'cpu': ['main-core', 'corelist-workers', 'skip-cores',
+ 'workers', 'scheduler-policy', 'scheduler-priority'],
+ 'dns': ['max-cache-size', 'max-ttl'],
+ 'dpdk': ['dev', 'vdev', 'name', 'hqos', 'rss',
+ 'no-multi-seg',
+ 'num-mbufs', 'num-rx-queues', 'num-tx-queues',
+ 'num-rx-desc', 'num-tx-desc',
+ 'socket-mem', 'no-tx-checksum-offload', 'uio-driver',
+ 'vlan-strip-offload', 'workers'],
+ # currently don't support dynamic keys
+ # 'heapsize': [],
+ 'l2learn': ['limit'],
+ 'l2tp': ['lookup-v6-src', 'lookup-v6-dst',
+ 'lookup-session-id'],
+ 'nat': ['connection tracking', 'deterministic', 'dslite ce',
+ 'endpoint-dependent', 'inside VRF id',
+ 'max translations per user',
+ 'nat64 bib hash bucket', 'nat64 bib hash memory',
+ 'nat64 st hash buckets',
+ 'outside ip6 VRF id', 'outside VRF id', 'out2in dpo'
+ 'static mapping only',
+ 'translation hash buckets',
+ 'translation hash memory',
+ 'user hash buckets', 'user hash memory',
+ ],
+ 'mactime': ['lookup-table-buckets', 'lookup-table-memory',
+ 'timezone_offset'],
+ 'mc': ['interface', 'no-delay', 'no-validate', 'max-delay',
+ 'min-delay', 'n-bytes', 'n-packets',
+ 'max-n-bytes',
+ 'min-n-bytes',
+ 'seed', 'window', 'verbose', ],
+ 'oam': ['interval', 'misses-allowed'],
+ 'plugins': ['path', 'plugin'],
+ 'punt': ['socket'],
+ 'session': ['event-queue-length', 'preallocated-sessions',
+ 'v4-session-table-buckets', 'v4-halfopen-table-buckets',
+ 'v6-session-table-buckets', 'v6-halfopen-table-buckets',
+ 'v6-halfopen-table-buckets'
+ ],
+ 'socksvr': ['default', 'socket-name'],
+ 'statseg': ['socket-name'],
+ 'tapcli': ['disable', 'mtu'],
+ 'tcp': ['buffer-fail-fraction', 'cc-algo', 'max-rx-fifo',
+ 'no-tx-pacing', 'preallocated-connections',
+ 'preallocated-half-open-connections',
+ ],
+ 'tuntap': ['name', 'mtu', 'enable', 'disable',
+ 'ether', 'ethernet',
+ 'have-normal', 'have-normal-interface'
+ ],
+ 'vhost-user': ['coalesce-frames', 'coalesce-time',
+ 'dont-dump-memory']
+
+
+ }
+ default_values = {'unix': {'interactive': None,
+ }
+ }
+
+ def __init__(self):
+ self.values = type(self).default_values
+ self.plugins = []
+
+ def add(self, stanza, key, val):
+ if stanza not in type(self).stanzas:
+ raise ValueError("stanza '%s' must be in %s" %
+ (stanza, type(self).stanzas))
+ if key not in type(self).kw[stanza]:
+ raise ValueError("key '%s' must be in %s" %
+ (key, type(self).kw[stanza]))
+ self.values[stanza][key] = val
+
+ def add_plugin(self, key, val):
+ self.plugins.append((key, val,))
+
+ def __str__(self):
+ result = ''
+ for stanza in type(self).stanzas:
+ try:
+ if self.values[stanza]:
+ result = '%s\n%s {' % (result, stanza)
+ for key in type(self).kw[stanza]:
+ try:
+ if key in self.values[stanza]:
+ result = '%s\n %s %s' % (
+ result, key,
+ self.values[stanza][key]
+ if self.values[stanza][key] is not
+ None else '')
+ except KeyError:
+ # no key: nothing to do
+ pass
+ if stanza == 'plugins' and key == 'plugin':
+ for plugin, val in self.plugins:
+ result = '%s\n plugin %s { % s }' % (
+ result, plugin,
+ val if val is not None else '')
+ result = '%s\n}\n' % result
+ except KeyError:
+ # no stanza not in self.values: nothing to do
+ pass
+ return result
+
+ def shlex(self):
+ return shlex.split(str(self))
+
+
+class MinimalVppConfig(VppConfig):
+ default_values = {'unix': {'interactive': None,
+ 'cli-listen': 'run/vpp/cli.sock',
+ 'gid': 1000
+ }
+ }
+
+
+class VppTestCaseVppConfig(VppConfig):
+ default_values = {'unix': {'nodaemon': None,
+ 'full-coredump': None,
+ },
+ 'acl-plugin': {},
+ 'api-queue': {},
+ 'api-trace': {'on': None},
+ 'api-segment': {},
+ 'cj': {},
+ 'cpu': {},
+ 'dns': {},
+ 'dpdk': {},
+ # currently don't support dynamic keys
+ # 'heapsize': {},
+ 'l2learn': {},
+ 'l2tp': {},
+ 'mactime': {},
+ 'mc': {},
+ 'nat': {},
+ 'oam': {},
+ 'plugins': {},
+ 'punt': {},
+ 'session': {},
+ 'socksvr': {'default': None},
+ 'statseg': {},
+ 'tapcli': {},
+ 'tcp': {},
+ 'tuntap': {},
+ 'vhost-user': {},
+ }
+
+
+class TestVppConfig(unittest.TestCase):
+
+ def setUp(self):
+ self.config = VppTestCaseVppConfig()
+
+ def test_unix(self):
+ size = None
+ tempdir = '/tmp'
+
+ # reset default values for this test.
+ self.config.default_values['unix'] = {}
+ self.config.add('unix', 'coredump-size', size
+ if size is not None else 'unlimited')
+ self.assertIn('unix {\n coredump-size unlimited\n}\n',
+ str(self.config))
+
+ self.config.add('unix', 'runtime-dir', tempdir)
+ self.assertIn('runtime-dir /tmp', str(self.config))
+
+ def test_api_segment(self):
+ shm_prefix = '/dev/shm'
+ self.config.add('api-segment', 'prefix', shm_prefix)
+ self.assertIn('api-segment {\n prefix /dev/shm\n}\n',
+ str(self.config))
+
+ def test_cpu(self):
+ luc = 0
+ self.config.add('cpu', 'main-core', str(luc))
+ self.assertIn('cpu {\n main-core 0\n}\n', str(self.config))
+
+ def test_statseg(self):
+ stats_sock = '/stats.sock'
+ self.config.add('statseg', 'socket-name', stats_sock)
+ self.assertIn('statseg {\n socket-name /stats.sock\n}\n',
+ str(self.config))
+
+ def test_plugin(self):
+ plugin_path = '/foo'
+ self.config.add('plugins', 'path', plugin_path)
+ self.assertIn('plugins {\n path /foo\n}\n',
+ str(self.config))
+
+ self.config.add_plugin('dpdk_plugin.so', 'disable')
+ self.config.add_plugin('unittest_plugin.so', 'enable')
+ self.assertIn('plugin dpdk_plugin.so { disable }\n',
+ str(self.config))
+ self.assertIn('plugin unittest_plugin.so { enable }\n',
+ str(self.config))
+
+
+if __name__ == '__main__':
+ unittest.main()