From 4830e4f78fb8e46b23a1a0711cd06969a77d8d95 Mon Sep 17 00:00:00 2001 From: Ray Kinsella Date: Tue, 10 Mar 2020 14:35:32 +0000 Subject: vlib: startup multi-arch variant configuration Support for startup node multi-arch variant selection through startup.conf. This is to facilitate unit, functional testing and benchmarking of non-default multi-arch variant node code path. Also added parameters to make test, to specific using multi-arch variants in unit testing. Type: improvement Signed-off-by: Ray Kinsella Change-Id: I94fd332bb629683b7a7dd770ee9f615a9a424060 --- test/Makefile | 4 ++ test/framework.py | 8 ++++ test/test_node_variants.py | 114 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 126 insertions(+) create mode 100644 test/test_node_variants.py (limited to 'test') diff --git a/test/Makefile b/test/Makefile index 6ba2e44f3cc..7d9d4e92e89 100644 --- a/test/Makefile +++ b/test/Makefile @@ -380,6 +380,10 @@ help: @echo " TEST='bfd.BFDAPITestCase.test_add_bfd' selects a single test named test_add_bfd from test_bfd.py/BFDAPITestCase" @echo " TEST='*.*.test_add_bfd' selects all test functions named test_add_bfd from all files/classes" @echo "" + @echo " VARIANT= - specify which march node variant to unit test" + @echo " e.g. VARIANT=avx2 test the avx2 march variants" + @echo " e.g. VARIANT=avx512 test the avx512 march variants" + @echo "" @echo " VPP_ZOMBIE_NOCHECK=1 - skip checking for vpp (zombie) processes (CAUTION)" @echo " COREDUMP_SIZE= - pass as unix { coredump-size } argument to vpp" @echo " e.g. COREDUMP_SIZE=4g" diff --git a/test/framework.py b/test/framework.py index c21d1882be7..19834026ef9 100644 --- a/test/framework.py +++ b/test/framework.py @@ -381,6 +381,12 @@ class VppTestCase(unittest.TestCase): if not hasattr(cls, "worker_config"): cls.worker_config = "" + default_variant = os.getenv("VARIANT") + if default_variant is not None: + default_variant = "defaults { %s 100 }" % default_variant + else: + default_variant = "" + cls.vpp_cmdline = [cls.vpp_bin, "unix", "{", "nodaemon", debug_cli, "full-coredump", coredump_size, "runtime-dir", cls.tempdir, "}", @@ -391,11 +397,13 @@ class VppTestCase(unittest.TestCase): "physmem", "{", "max-size", "32m", "}", "statseg", "{", "socket-name", cls.stats_sock, "}", "socksvr", "{", "socket-name", cls.api_sock, "}", + "node { ", default_variant, "}", "plugins", "{", "plugin", "dpdk_plugin.so", "{", "disable", "}", "plugin", "rdma_plugin.so", "{", "disable", "}", "plugin", "unittest_plugin.so", "{", "enable", "}"] + cls.extra_vpp_plugin_config + ["}", ] + if cls.extra_vpp_punt_config is not None: cls.vpp_cmdline.extend(cls.extra_vpp_punt_config) if plugin_path is not None: diff --git a/test/test_node_variants.py b/test/test_node_variants.py new file mode 100644 index 00000000000..8298dc863a4 --- /dev/null +++ b/test/test_node_variants.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python3 +import re +import unittest +import platform +from framework import VppTestCase + + +def checkX86(): + return platform.machine() in ["x86_64", "AMD64"] + + +def skipVariant(variant): + with open("/proc/cpuinfo") as f: + cpuinfo = f.read() + + exp = re.compile( + r'(?:flags\s+:)(?:\s\w+)+(?:\s(' + variant + r'))(?:\s\w+)+') + match = exp.search(cpuinfo, re.DOTALL | re.MULTILINE) + + return checkX86() and match is not None + + +class TestNodeVariant(VppTestCase): + """ Test Node Variants """ + + @classmethod + def setUpConstants(cls, variant): + super(TestNodeVariant, cls).setUpConstants() + # find the position of node_variants in the cmdline args. + + if checkX86(): + node_variants = cls.vpp_cmdline.index("node { ") + 1 + cls.vpp_cmdline[node_variants] = ("default { variant default } " + "ip4-rewrite { variant " + + variant + " } ") + + @classmethod + def setUpClass(cls): + super(TestNodeVariant, cls).setUpClass() + + @classmethod + def tearDownClass(cls): + super(TestNodeVariant, cls).tearDownClass() + + def setUp(self): + super(TestNodeVariant, self).setUp() + + def tearDown(self): + super(TestNodeVariant, self).tearDown() + + def getActiveVariant(self, node): + node_desc = self.vapi.cli("show node " + node) + self.logger.info(node_desc) + + match = re.search(r'\s+(\S+)\s+(\d+)\s+(:?yes)', + node_desc, re.DOTALL | re.MULTILINE) + + return match.groups(0) + + def checkVariant(self, variant): + """ Test node variants defaults """ + + variant_info = self.getActiveVariant("ip4-lookup") + self.assertEqual(variant_info[0], "default") + + variant_info = self.getActiveVariant("ip4-rewrite") + self.assertEqual(variant_info[0], variant) + + +class TestAVX512Variant(TestNodeVariant): + """ Test avx512 Node Variants """ + + VARIANT = "avx512" + LINUX_VARIANT = VARIANT + "f" + + @classmethod + def setUpConstants(cls): + super(TestAVX512Variant, cls).setUpConstants(cls.VARIANT) + + @classmethod + def setUpClass(cls): + super(TestAVX512Variant, cls).setUpClass() + + @classmethod + def tearDownClass(cls): + super(TestAVX512Variant, cls).tearDownClass() + + @unittest.skipUnless(skipVariant(LINUX_VARIANT), + VARIANT + " not a supported variant, skip.") + def test_avx512(self): + self.checkVariant(self.VARIANT) + + +class TestAVX2Variant(TestNodeVariant): + """ Test avx2 Node Variants """ + + VARIANT = "avx2" + + @classmethod + def setUpConstants(cls): + super(TestAVX2Variant, cls).setUpConstants(cls.VARIANT) + + @classmethod + def setUpClass(cls): + super(TestAVX2Variant, cls).setUpClass() + + @classmethod + def tearDownClass(cls): + super(TestAVX2Variant, cls).tearDownClass() + + @unittest.skipUnless(skipVariant(VARIANT), + VARIANT + " not a supported variant, skip.") + def test_avx2(self): + self.checkVariant(self.VARIANT) -- cgit 1.2.3-korg