Best Python code snippet using avocado_python
ndctl.py
Source:ndctl.py  
...46        if region:47            return region48        regions = self.plib.run_ndctl_list('-R')49        regions = sorted(regions, key=lambda i: i['size'], reverse=True)50        return self.plib.run_ndctl_list_val(regions[0], 'dev')51    @staticmethod52    def get_unsupported_alignval(def_align):53        """54        Return alternate size align for negative case55        """56        if def_align == 16777216:57            return 209715258        return 1677721659    @staticmethod60    def lcm(one, two):61        return abs(one * two) // math.gcd(one, two)62    def check_namespace_align(self, region):63        """64        Utility to check if the namespaces of given region adapts following65        1. Aligning of sys fs map_align attribute and ndctl list align value66        2. The size after creation is a multiple of the map_align67        Note: Function to be used after creation of namespace(s)68        """69        idx = re.findall(r'\d+', region)[0]70        map_align = int(genio.read_one_line(71            "/sys/bus/nd/devices/pfn%s.0/align" % idx))72        namespaces = self.plib.run_ndctl_list('-N -r %s' % region)73        for ns in namespaces:74            ns_name = self.plib.run_ndctl_list_val(ns, 'dev')75            namespace = self.plib.run_ndctl_list('-n %s' % ns_name)[0]76            ndctl_align = self.plib.run_ndctl_list_val(namespace, 'align')77            if map_align != ndctl_align:78                self.fail("Mismatch in mapping alignment and ndctl list align")79            ndctl_size = self.plib.run_ndctl_list_val(namespace, 'size')80            print(ndctl_size, map_align)81            if ndctl_size % map_align:82                self.fail("Created Size is not a multiple of map alignment")83    def get_size_alignval(self):84        """85        Return the size align restriction based on platform86        """87        if not os.path.exists("/sys/bus/nd/devices/region0/align"):88            size_align = 189        else:90            size_align = int(genio.read_one_line(91                "/sys/bus/nd/devices/region0/align"), 16)92        if not os.path.exists("/sys/bus/nd/devices/pfn0.0/align"):93            self.cancel("Cannot determine the mapping alignment size")94        map_align = int(genio.read_one_line(95            "/sys/bus/nd/devices/pfn0.0/align"))96        return self.lcm(size_align, map_align)97    def build_fio(self):98        """99        Install fio or build if not possible100        """101        pkg = "fio"102        if process.system("which %s" % pkg, ignore_status=True):103            if not self.smm.check_installed(pkg) \104                    and not self.smm.install(pkg):105                for package in ["autoconf", "libtool", "make"]:106                    if not self.smm.check_installed(package) \107                            and not self.smm.install(package):108                        self.cancel(109                            "Fail to install %s required for this test."110                            "" % package)111                tarball = self.fetch_asset(112                    "http://brick.kernel.dk/snaps/fio-2.1.10.tar.gz")113                archive.extract(tarball, self.teststmpdir)114                fio_version = os.path.basename(tarball.split('.tar.')[0])115                sourcedir = os.path.join(self.teststmpdir, fio_version)116                build.make(sourcedir)117                return os.path.join(sourcedir, "fio")118        return pkg119    def copyutil(self, file_name, iniparser_dir):120        shutil.copy(file_name, iniparser_dir)121    def autotools_build_system(self):122        # Check if /usr/include/iniparser directory is present or not123        # If not present then create it and then  copy the iniparser.h124        # and dictionary.h headers to /usr/include/iniparser/125        # Skip this code for releases which ships required header files126        # as a part of /usr/include/iniparser/ directory.127        if not self.dist.name == 'rhel':128            iniparser_dir = "/usr/include/iniparser/"129            if not os.path.exists(iniparser_dir):130                os.makedirs(iniparser_dir)131            for file_name in ['/usr/include/iniparser.h',132                              '/usr/include/dictionary.h']:133                self.copyutil(file_name, iniparser_dir)134        process.run('./autogen.sh', sudo=True, shell=True)135        process.run("./configure CFLAGS='-g -O2' --prefix=/usr "136                    "--disable-docs "137                    "--sysconfdir=/etc --libdir="138                    "/usr/lib64", shell=True, sudo=True)139        build.make(".")140        self.ndctl = os.path.abspath('./ndctl/ndctl')141        self.daxctl = os.path.abspath('./daxctl/daxctl')142    def meson_build_system(self, deps):143        deps.extend(['xmlto', 'libuuid-devel', 'meson', 'cmake'])144        if self.dist.name == 'SuSE':145            deps.extend(['libgudev-1_0-devel', 'libiniparser1', 'pkg-config',146                         'ruby2.5-rubygem-asciidoctor-doc',147                         'systemd-rpm-macros', 'libiniparser-devel'])148        elif self.dist.name == 'rhel':149            deps.extend(['libgudev-devel', 'rubygem-asciidoctor'])150        for pkg in deps:151            if not self.smm.check_installed(pkg) and not self.smm.install(pkg):152                self.cancel('%s is needed for the test to be run' % pkg)153        process.run("meson setup build", sudo=True, shell=True)154        process.run("meson install -C build", sudo=True, shell=True)155        self.ndctl = os.path.abspath('/usr/bin/ndctl')156        self.daxctl = os.path.abspath('/usr/bin/daxctl')157    def setUp(self):158        """159        Build 'ndctl' and setup the binary.160        """161        deps = []162        self.dist = distro.detect()163        self.package = self.params.get('package', default='upstream')164        self.preserve_setup = self.params.get('preserve_change', default=False)165        self.mode_to_use = self.params.get('modes', default='fsdax')166        location = self.params.get('location', default='.')167        ndctl_project_version = self.params.get(168            'ndctl_project_version', default='')169        url = "https://github.com/pmem/ndctl.git"170        if self.dist.name not in ['SuSE', 'rhel']:171            self.cancel('Unsupported OS %s' % self.dist.name)172        # DAX wont work with reflink, disabling here173        self.reflink = '-m reflink=0'174        self.smm = SoftwareManager()175        if self.package == 'upstream':176            deps.extend(['gcc', 'make', 'automake', 'autoconf'])177            if self.dist.name == 'SuSE':178                # Cancel this for now, due to non-availibility of179                # dependent packages for suse versions below sles15sp3.180                if self.dist.release < 3:181                    self.cancel("Cancelling the test due to "182                                "non-availability of dependent packages.")183                else:184                    deps.extend(['libtool', 'libkmod-devel', 'libudev-devel',185                                 'systemd-devel', 'libuuid-devel-static',186                                 'libjson-c-devel', 'keyutils-devel',187                                 'kmod-bash-completion',188                                 'bash-completion-devel'])189            elif self.dist.name == 'rhel':190                deps.extend(['libtool', 'bash-completion', 'parted',191                             'kmod-devel', 'libuuid-devel', 'json-c-devel',192                             'systemd-devel', 'keyutils-libs-devel', 'jq',193                             'iniparser', 'iniparser-devel'])194            for pkg in deps:195                if not self.smm.check_installed(pkg) and not \196                        self.smm.install(pkg):197                    self.cancel('%s is needed for the test to be run' % pkg)198            if ndctl_project_version:199                ndctl_tag_name = "v" + ndctl_project_version200                # Clone the 'main' branch201                git.get_repo(url, branch='main',202                             destination_dir=self.teststmpdir)203                os.chdir(self.teststmpdir)204                # Checkout the desired tag205                git_helper = GitRepoHelper(206                    url, destination_dir=self.teststmpdir)207                git_helper.checkout(branch=ndctl_tag_name, commit=None)208                if (float(ndctl_project_version) < 73):209                    self.autotools_build_system()210                else:211                    self.meson_build_system(deps)212            # default to the meson way of building ndctl library213            else:214                # Clone the 'pending' branch215                git_branch = self.params.get('git_branch', default='pending')216                git.get_repo(url, branch=git_branch,217                             destination_dir=self.teststmpdir)218                os.chdir(self.teststmpdir)219                self.meson_build_system(deps)220        elif self.package == 'local':221            self.ndctl = os.path.abspath(os.path.join(location, 'ndctl/ndctl'))222            self.daxctl = os.path.abspath(223                os.path.join(location, 'daxctl/daxctl'))224        else:225            deps.extend(['ndctl'])226            if self.dist.name == 'rhel':227                deps.extend(['daxctl'])228            for pkg in deps:229                if not self.smm.check_installed(pkg) and not \230                        self.smm.install(pkg):231                    self.cancel('%s is needed for the test to be run' % pkg)232            self.ndctl = 'ndctl'233            self.daxctl = 'daxctl'234        self.opt_dict = {'-B': 'provider',235                         '-D': 'dev', '-R': 'dev', '-N': 'dev'}236        self.modes = ['raw', 'sector', 'fsdax', 'devdax']237        self.part = None238        self.disk = None239        self.plib = pmem.PMem(self.ndctl, self.daxctl)240        if not self.plib.check_buses():241            self.cancel("Test needs atleast one region")242    @avocado.fail_on(pmem.PMemException)243    def test_bus_ids(self):244        """245        Test the bus id info246        """247        vals = self.plib.run_ndctl_list('-B')248        if not vals:249            self.fail('Failed to fetch bus IDs')250        self.log.info('Available Bus provider IDs: %s', vals)251    @avocado.fail_on(pmem.PMemException)252    def test_dimms(self):253        """254        Test the dimms info255        """256        vals = self.plib.run_ndctl_list('-D')257        if not vals:258            self.fail('Failed to fetch DIMMs')259        self.log.info('Available DIMMs: %s', vals)260    @avocado.fail_on(pmem.PMemException)261    def test_dimm_health(self):262        """263        Test the dimm health264        """265        dimms = self.plib.run_ndctl_list('-DH')266        if not dimms:267            self.fail('Failed to fetch DIMMs')268        for dimm in dimms:269            health = self.plib.run_ndctl_list_val(dimm, 'health')270            nmem = self.plib.run_ndctl_list_val(dimm, 'dev')271            region = "region%s" % re.findall(r'\d+', nmem)[0]272            dev_type = genio.read_one_line(273                "/sys/bus/nd/devices/%s/devtype" % region)274            if not health:275                self.cancel("kernel/ndctl does not support health reporting")276            if dev_type == "nd_pmem":277                if 'life_used_percentage' not in health:278                    self.fail("life_used_percentage missing for HMS")279                self.log.info("%s life is %s", nmem,280                              health['life_used_percentage'])281            if 'health_state' in health:282                if health['health_state'] != "ok":283                    self.log.warn("%s health is bad", nmem)284            if 'shutdown_state' in health:285                if health['shutdown_state'] != "clean":286                    self.log.warn("%s shutdown state is dirty", nmem)287            self.log.info("DIMM %s Health info: %s", nmem, health)288    @avocado.fail_on(pmem.PMemException)289    def test_regions(self):290        """291        Test the regions info292        """293        self.plib.disable_region()294        old = self.plib.run_ndctl_list('-R')295        self.plib.enable_region()296        new = self.plib.run_ndctl_list('-R')297        if len(new) <= len(old):298            self.fail('Failed to fetch regions')299        self.log.info('Available regions: %s', new)300    @avocado.fail_on(pmem.PMemException)301    def test_namespace(self):302        """303        Test namespace304        """305        self.plib.enable_region()306        regions = self.plib.run_ndctl_list('-R')307        for val in regions:308            region = self.plib.run_ndctl_list_val(val, 'dev')309            self.plib.disable_namespace(region=region)310            self.plib.destroy_namespace(region=region)311            self.plib.create_namespace(region=region)312            self.check_namespace_align(region)313        namespaces = self.plib.run_ndctl_list('-N')314        self.log.info('Created namespace %s', namespaces)315    @avocado.fail_on(pmem.PMemException)316    def test_namespace_unaligned(self):317        """318        Test namespace319        """320        self.plib.enable_region()321        # Use an default unaligned pagesize and make sure it fails322        align_size = memory.get_page_size()323        size = (64 * 1024 * 1024) + align_size324        regions = self.plib.run_ndctl_list('-R')325        for val in regions:326            region = self.plib.run_ndctl_list_val(val, 'dev')327            self.plib.disable_namespace(region=region)328            self.plib.destroy_namespace(region=region)329            try:330                self.plib.create_namespace(331                    region=region, size=size, align=align_size)332            except pmem.PMemException:333                self.log.info("Unaligned namespace creation failed"334                              "as expected")335            else:336                self.fail("Unaligned namespace creation must have failed! ")337    @avocado.fail_on(pmem.PMemException)338    def test_disable_enable_ns(self):339        """340        Test enable disable namespace341        """342        region = self.get_default_region()343        if (not self.plib.is_region_legacy(region)):344            size = self.plib.run_ndctl_list_val(self.plib.run_ndctl_list(345                '-r %s' % region)[0], 'size')346            if size < (3 * 64 * 1024 * 1024):347                self.cancel('Not enough memory to create namespaces')348            for _ in range(0, 3):349                self.plib.create_namespace(region=region, size='64M')350        namespaces = self.plib.run_ndctl_list('-N')351        ns_names = []352        for ns in namespaces:353            ns_names.append(self.plib.run_ndctl_list_val(ns, 'dev'))354        ns_names.append('all')355        for namespace in ns_names:356            self.plib.disable_namespace(namespace=namespace)357            self.plib.enable_namespace(namespace=namespace)358    @avocado.fail_on(pmem.PMemException)359    def test_namespace_modes(self):360        """361        Create  different namespace types362        """363        failed_modes = []364        region = self.get_default_region()365        self.log.info("Using %s for different namespace modes", region)366        self.plib.disable_namespace(region=region)367        self.plib.destroy_namespace(region=region)368        for mode in self.modes:369            self.plib.create_namespace(region=region, mode=mode)370            ns_json = self.plib.run_ndctl_list('-r %s -N' % region)[0]371            created_mode = self.plib.run_ndctl_list_val(ns_json, 'mode')372            if mode != created_mode:373                failed_modes.append(mode)374                self.log.error("Expected mode %s, Got %s", mode, created_mode)375            else:376                self.log.info("Namespace with %s mode: %s", mode, ns_json)377            ns_name = self.plib.run_ndctl_list_val(ns_json, 'dev')378            self.plib.disable_namespace(namespace=ns_name, region=region)379            self.plib.destroy_namespace(namespace=ns_name, region=region)380        if failed_modes:381            self.fail("Namespace for %s mode failed!" % failed_modes)382    @avocado.fail_on(pmem.PMemException)383    def test_namespace_devmap(self):384        """385        Test metadata device mapping option with a namespace386        """387        region = self.get_default_region()388        m_map = self.params.get('map', default='mem')389        self.log.info("Using %s for checking device mapping", region)390        self.plib.disable_namespace(region=region)391        self.plib.destroy_namespace(region=region)392        self.plib.create_namespace(region=region, mode=self.mode_to_use,393                                   memmap=m_map)394        self.log.info("Validating device mapping")395        map_val = self.plib.run_ndctl_list_val(self.plib.run_ndctl_list(396            '-r %s -N' % region)[0], 'map')397        if map_val != m_map:398            self.fail("Expected map:%s, Got %s" % (m_map, map_val))399        else:400            self.log.info("Metadata mapped as expected")401    def multiple_namespaces_region(self, region):402        """403        Test multiple namespace with single region404        """405        namespace_size = self.params.get('size', default=None)406        size_align = self.get_size_alignval()407        slot_count = self.plib.get_slot_count(region)408        self.log.info("Using %s for muliple namespace regions", region)409        self.plib.disable_namespace(region=region)410        self.plib.destroy_namespace(region=region)411        if namespace_size and ((namespace_size % size_align) != 0):412            self.cancel("Size value not %d aligned %d \n",413                        size_align, namespace_size)414        region_size = self.plib.run_ndctl_list_val(self.plib.run_ndctl_list(415            '-r %s' % region)[0], 'size')416        if not namespace_size:417            namespace_size = region_size // slot_count418            # Now align the namespace size419            namespace_size = (namespace_size // size_align) * size_align420        else:421            slot_count = region_size // namespace_size422        if namespace_size <= size_align:423            self.log.warn("Ns size equal to pagesize, hence skipping region")424            return425        self.log.info("Creating %s namespaces", slot_count)426        for count in range(0, slot_count):427            self.plib.create_namespace(428                region=region, mode=self.mode_to_use, size=namespace_size)429            self.log.info("Namespace %s created", count + 1)430    @avocado.fail_on(pmem.PMemException)431    def test_multiple_namespaces_region(self):432        """433        Test multiple namespace with single region434        """435        region = self.get_default_region()436        if (self.plib.is_region_legacy(region)):437            self.cancel("Legacy config skipping the test")438        self.multiple_namespaces_region(region)439        self.check_namespace_align(region)440    @avocado.fail_on(pmem.PMemException)441    def test_multiple_ns_multiple_region(self):442        """443        Test multiple namespace with multiple region444        """445        self.plib.enable_region()446        if len(self.plib.run_ndctl_list('-R')) <= 1:447            self.cancel("Test not applicable without multiple regions")448        regions = self.plib.run_ndctl_list('-R')449        self.plib.disable_namespace()450        self.plib.destroy_namespace()451        for val in regions:452            region = self.plib.run_ndctl_list_val(val, 'dev')453            if (self.plib.is_region_legacy(region)):454                self.cancel("Legacy config skipping the test")455            self.multiple_namespaces_region(region)456            self.check_namespace_align(region)457    @avocado.fail_on(pmem.PMemException)458    def test_multiple_ns_modes_region(self):459        """460        Test multiple namespace modes with single region461        """462        region = self.get_default_region()463        if (self.plib.is_region_legacy(region)):464            self.cancel("Legacy config skipping the test")465        self.log.info("Using %s for muliple namespace regions", region)466        self.plib.disable_namespace(region=region)467        self.plib.destroy_namespace(region=region)468        size = self.plib.run_ndctl_list_val(self.plib.run_ndctl_list(469            '-r %s' % region)[0], 'size')470        if size < (len(self.modes) * 64 * 1024 * 1024):471            self.cancel('Not enough memory to create namespaces')472        for mode in self.modes:473            self.plib.create_namespace(474                region=region, mode=mode, size='64M')475            self.log.info("Namespace of type %s created", mode)476    @avocado.fail_on(pmem.PMemException)477    def test_nslot_namespace(self):478        """479        Test max namespace with nslot value480        """481        region = self.get_default_region()482        if (self.plib.is_region_legacy(region)):483            self.cancel("Legacy config skipping the test")484        size_align = self.get_size_alignval()485        slot_count = self.plib.get_slot_count(region)486        self.log.info("Using %s for max namespace creation", region)487        self.plib.disable_namespace()488        self.plib.destroy_namespace()489        region_size = self.plib.run_ndctl_list_val(self.plib.run_ndctl_list(490            '-r %s' % region)[0], 'size')491        namespace_size = region_size // slot_count492        # Now align the namespace size493        namespace_size = (namespace_size // size_align) * size_align494        self.log.info("Creating %s namespace", slot_count)495        for count in range(0, slot_count):496            self.plib.create_namespace(region=region, mode='fsdax',497                                       size=namespace_size)498            self.log.info("Namespace %s created", count)499        self.check_namespace_align(region)500    @avocado.fail_on(pmem.PMemException)501    def test_namespace_reconfigure(self):502        """503        Test namespace reconfiguration504        """505        region = self.get_default_region()506        self.log.info("Using %s for reconfiguring namespace", region)507        self.plib.disable_namespace()508        self.plib.destroy_namespace()509        self.plib.create_namespace(region=region, mode='fsdax', align='64k')510        old_ns = self.plib.run_ndctl_list()[0]511        old_ns_dev = self.plib.run_ndctl_list_val(old_ns, 'dev')512        self.log.info("Re-configuring namespace %s", old_ns_dev)513        self.plib.create_namespace(region=region, mode='fsdax', name='test_ns',514                                   reconfig=old_ns_dev, force=True)515        new_ns = self.plib.run_ndctl_list()[0]516        self.log.info("Checking namespace changes")517        failed_vals = []518        for key, val in new_ns.items():519            if key in list(set(old_ns.keys()) - set(['uuid', 'dev'])):520                if old_ns[key] != val:521                    failed_vals.append({key: val})522            else:523                self.log.info("Newly added filed %s:%s", key, val)524        if failed_vals:525            self.fail("New namespace unexpected change(s): %s" % failed_vals)526    @avocado.fail_on(pmem.PMemException)527    def test_check_namespace(self):528        """529        Verify metadata for sector mode namespaces530        """531        region = self.get_default_region()532        self.plib.disable_namespace()533        self.plib.destroy_namespace()534        self.log.info("Creating sector namespace using %s", region)535        self.plib.create_namespace(region=region, mode='sector')536        ns_sec_dev = self.plib.run_ndctl_list_val(537            self.plib.run_ndctl_list()[0], 'dev')538        self.plib.disable_namespace(namespace=ns_sec_dev)539        self.log.info("Checking BTT metadata")540        if process.system("%s check-namespace %s" % (self.ndctl, ns_sec_dev),541                          ignore_status=True):542            self.fail("Failed to check namespace metadata")543    @avocado.fail_on(pmem.PMemException)544    def test_check_numa(self):545        self.plib.enable_region()546        regions = self.plib.run_ndctl_list('-R')547        if not os.path.exists('/sys/bus/nd/devices/region0/numa_node'):548            self.fail("Numa node entries not found!")549        for val in regions:550            reg = self.plib.run_ndctl_list_val(val, 'dev')551            numa = genio.read_one_line(552                '/sys/bus/nd/devices/%s/numa_node' % reg)553            # Check numa config in ndctl and sys interface554            if len(self.plib.run_ndctl_list('-r %s -R -U %s'555                                            % (reg, numa))) != 1:556                self.fail('Region mismatch between ndctl and sys interface')557    @avocado.fail_on(pmem.PMemException)558    def test_check_ns_numa(self):559        self.plib.enable_region()560        regions = self.plib.run_ndctl_list('-R')561        for dev in regions:562            region = self.plib.run_ndctl_list_val(dev, 'dev')563            if not self.plib.is_region_legacy(region):564                self.plib.disable_namespace(region=region)565                self.plib.destroy_namespace(region=region)566                size = self.plib.run_ndctl_list_val(dev, 'size')567                if size < (3 * 64 * 1024 * 1024):568                    self.log.warn('Skipping region due to insufficient memory')569                    continue570                for _ in range(3):571                    self.plib.create_namespace(572                        region=region, mode='fsdax', size='64M')573            namespaces = self.plib.run_ndctl_list('-N -r %s' % region)574            if not os.path.exists(575                    '/sys/bus/nd/devices/namespace0.0/numa_node'):576                self.fail("Numa node entries not found!")577            for val in namespaces:578                ns_name = self.plib.run_ndctl_list_val(val, 'dev')579                numa = genio.read_one_line(580                    '/sys/bus/nd/devices/%s/numa_node' % ns_name)581                # Check numa config in ndctl and sys interface582                if len(self.plib.run_ndctl_list('-N -n %s -U %s'583                                                % (ns_name, numa))) != 1:584                    self.fail('Numa mismatch between ndctl and sys interface')585    @avocado.fail_on(pmem.PMemException)586    def test_label_read_write(self):587        region = self.get_default_region()588        if (self.plib.is_region_legacy(region)):589            self.cancel("Legacy config skipping the test")590        nmem = "nmem%s" % re.findall(r'\d+', region)[0]591        self.log.info("Using %s for testing labels", region)592        self.plib.disable_region(name=region)593        self.log.info("Filling zeros to start test")594        if process.system('%s zero-labels %s'595                          % (self.ndctl, nmem), shell=True):596            self.fail("Label zero-fill failed")597        self.plib.enable_region(name=region)598        self.plib.create_namespace(region=region)599        self.log.info("Storing labels with a namespace")600        old_op = process.system_output(601            '%s check-labels %s' % (self.ndctl, nmem), shell=True)602        if process.system('%s read-labels %s -o output'603                          % (self.ndctl, nmem), shell=True):604            self.fail("Label read failed")605        self.log.info("Refilling zeroes before a restore")606        self.plib.disable_namespace(region=region)607        self.plib.destroy_namespace(region=region)608        self.plib.disable_region(name=region)609        if process.system('%s zero-labels %s'610                          % (self.ndctl, nmem), shell=True):611            self.fail("Label zero-fill failed after read")612        self.log.info("Re-storing labels with a namespace")613        if process.system('%s write-labels %s -i output'614                          % (self.ndctl, nmem), shell=True):615            self.fail("Label write failed")616        self.plib.enable_region(name=region)617        self.log.info("Checking mismatch after restore")618        new_op = process.system_output(619            '%s check-labels %s' % (self.ndctl, nmem), shell=True)620        if new_op != old_op:621            self.fail("Label read and write mismatch")622        self.log.info("Checking created namespace after restore")623        if len(self.plib.run_ndctl_list('-N -r %s' % region)) != 1:624            self.fail("Created namespace not found after label restore")625    @avocado.fail_on(pmem.PMemException)626    def test_daxctl_list(self):627        """628        Test daxctl list629        """630        region = self.get_default_region()631        self.plib.disable_namespace(region=region)632        self.plib.destroy_namespace(region=region)633        self.plib.create_namespace(region=region, mode='devdax')634        index = re.findall(r'\d+', region)[0]635        vals = self.plib.run_daxctl_list('-r %s' % (index))636        if len(vals) != 1:637            self.fail('Failed daxctl list')638        self.log.info('Created dax device %s', vals)639    @avocado.fail_on(pmem.PMemException)640    def test_region_capabilities(self):641        """642        Test region capabilities643        """644        self.plib.enable_region()645        self.plib.disable_namespace()646        self.plib.destroy_namespace()647        regions = self.plib.run_ndctl_list('-R -C')648        for region in regions:649            cap = self.plib.run_ndctl_list_val(region, 'capabilities')650            sec_sizes = []651            fsdax_align = []652            devdax_align = []653            for typ in cap:654                mode = self.plib.run_ndctl_list_val(typ, 'mode')655                if mode == 'fsdax':656                    fsdax_align = self.plib.run_ndctl_list_val(657                        typ, 'alignments')658                elif mode == 'devdax':659                    devdax_align = self.plib.run_ndctl_list_val(660                        typ, 'alignments')661                elif mode == 'sector':662                    sec_sizes = self.plib.run_ndctl_list_val(663                        typ, 'sector_sizes')664            reg_name = self.plib.run_ndctl_list_val(region, 'dev')665            self.log.info("Creating namespaces with possible sizes")666            for size in sec_sizes:667                self.plib.create_namespace(668                    region=reg_name, mode='sector', sector_size=size)669                self.plib.destroy_namespace(region=reg_name, force=True)670            for size in fsdax_align:671                self.plib.create_namespace(672                    region=reg_name, mode='fsdax', align=size)673                self.plib.destroy_namespace(region=reg_name, force=True)674            for size in devdax_align:675                self.plib.create_namespace(676                    region=reg_name, mode='devdax', align=size)677                self.plib.destroy_namespace(region=reg_name, force=True)678    @avocado.fail_on(pmem.PMemException)679    def test_daxctl_memhotplug_unplug(self):680        """681        Test devdax memory hotplug/unplug682        """683        for cmd in ["reconfigure-device", "offline-memory", "online-memory"]:684            if not self.plib.check_daxctl_subcmd(cmd):685                self.cancel("Binary does not support %s" % cmd)686        region = self.get_default_region()687        self.plib.disable_namespace(region=region)688        self.plib.destroy_namespace(region=region)689        self.plib.create_namespace(region=region, mode='devdax')690        daxdev = self.plib.run_ndctl_list_val(691            self.plib.run_ndctl_list("-N -r %s" % region)[0], 'chardev')692        old_mem = memory.meminfo.MemTotal.b693        dev_prop = self.plib.reconfigure_dax_device(daxdev, mode="system-ram")694        self.log.info("Reconfigured device %s", dev_prop)695        new_mem = memory.meminfo.MemTotal.b696        self.log.info("Memory Before:%s, Memory After:%s", old_mem, new_mem)697        if new_mem <= old_mem:698            self.log.warn("Memorysize not increased %s<=%s", new_mem, old_mem)699        self.plib.set_dax_memory_offline(daxdev)700        unplug_mem = memory.meminfo.MemTotal.b701        if unplug_mem != old_mem:702            self.fail("Memory after unplug is not same as system memory")703        self.log.info("Memory restored to base memory after unplug")704        self.plib.set_dax_memory_online(daxdev)705        hplug_mem = memory.meminfo.MemTotal.b706        if hplug_mem != new_mem:707            self.fail("Memory after hotplug is not same as device size memory")708        self.log.info("Memory hotplug successful with pmem device")709        self.log.info("Restoring pmem device in devdax mode")710        self.plib.set_dax_memory_offline(daxdev)711        self.plib.reconfigure_dax_device(daxdev, mode="devdax")712    @avocado.fail_on(pmem.PMemException)713    def write_read_infoblock(self, ns_name, align='', size=''):714        """715        Write_infoblock on given namespace716        """717        self.plib.write_infoblock(namespace=ns_name, align=align,718                                  size=size, mode='devdax')719        read_out = self.plib.read_infoblock(namespace=ns_name)720        if align:721            if align != int(self.plib.run_ndctl_list_val722                            (read_out[0], 'align')):723                self.fail("Alignment has not changed")724        return read_out[0]725    @avocado.fail_on(pmem.PMemException)726    def test_write_infoblock_supported_align(self):727        """728        Test write_infoblock with align size729        """730        if not self.plib.check_ndctl_subcmd("write-infoblock"):731            self.cancel("Binary does not support write-infoblock")732        region = self.get_default_region()733        self.plib.disable_namespace(region=region)734        self.plib.destroy_namespace(region=region)735        self.plib.create_namespace(region=region, mode='devdax')736        ns_name = self.plib.run_ndctl_list_val(737            self.plib.run_ndctl_list("-N -r %s" % region)[0], 'dev')738        self.plib.disable_namespace(namespace=ns_name)739        map_align = memory.get_supported_huge_pages_size()[0] * 1024740        self.write_read_infoblock(ns_name, align=map_align)741        self.plib.enable_namespace(namespace=ns_name)742    @avocado.fail_on(pmem.PMemException)743    def test_write_infoblock_unalign(self):744        """745        Test write_infoblock with unsupported align size746        """747        if not self.plib.check_ndctl_subcmd("write-infoblock"):748            self.cancel("Binary does not support write-infoblock")749        region = self.get_default_region()750        self.plib.disable_namespace(region=region)751        self.plib.destroy_namespace(region=region)752        self.plib.create_namespace(region=region, mode='devdax')753        ns_name = self.plib.run_ndctl_list_val(754            self.plib.run_ndctl_list("-N -r %s" % region)[0], 'dev')755        self.plib.disable_namespace(namespace=ns_name)756        map_align = memory.get_supported_huge_pages_size()[0] * 1024757        self.write_read_infoblock(758            ns_name, align=self.get_unsupported_alignval(map_align))759        try:760            self.plib.enable_namespace(namespace=ns_name)761        except pmem.PMemException:762            self.log.info("Failed as expected")763        else:764            self.log.info(self.plib.run_ndctl_list())765            self.fail("Enabling namespace must have failed")766        idle_ns = self.plib.run_ndctl_list('-Ni -r %s' % region)767        if len(idle_ns) > 1:768            found = False769            for namespace in idle_ns:770                if int(self.plib.run_ndctl_list_val(namespace, 'size')) != 0:771                    found = True772                    break773        else:774            self.fail("Created namespace is not found")775        if not found:776            self.fail("Namespace with infoblock written not found")777        self.plib.destroy_namespace(namespace=ns_name, force=True)778    @avocado.fail_on(pmem.PMemException)779    def test_write_infoblock_align_default(self):780        """781        Test write_infoblock with align size782        """783        if not self.plib.check_ndctl_subcmd("write-infoblock"):784            self.cancel("Binary does not support write-infoblock")785        region = self.get_default_region()786        self.plib.disable_namespace(region=region)787        self.plib.destroy_namespace(region=region)788        self.plib.create_namespace(region=region, mode='devdax')789        ns_name = self.plib.run_ndctl_list_val(790            self.plib.run_ndctl_list("-N -r %s" % region)[0], 'dev')791        align = self.plib.run_ndctl_list_val(792            self.plib.run_ndctl_list("-N -r %s" % region)[0], 'align')793        self.plib.disable_namespace(namespace=ns_name)794        write_block = self.write_read_infoblock(ns_name)795        if align != self.plib.run_ndctl_list_val(write_block, 'align'):796            self.fail("Alignment is not same as default alignment")797    @avocado.fail_on(pmem.PMemException)798    def test_write_infoblock_size(self):799        """800        Test write_infoblock with align size801        """802        if not self.plib.check_ndctl_subcmd("write-infoblock"):803            self.cancel("Binary does not support write-infoblock")804        region = self.get_default_region()805        self.plib.disable_namespace(region=region)806        self.plib.destroy_namespace(region=region)807        self.plib.create_namespace(region=region, mode='devdax')808        ns_name = self.plib.run_ndctl_list_val(809            self.plib.run_ndctl_list("-N -r %s" % region)[0], 'dev')810        size = self.plib.run_ndctl_list_val(811            self.plib.run_ndctl_list("-N -r %s" % region)[0], 'size')812        self.plib.disable_namespace(namespace=ns_name)813        align = self.get_size_alignval()814        size = size - align815        self.write_read_infoblock(ns_name, size=size)816        self.plib.enable_namespace(namespace=ns_name)817    @avocado.fail_on(pmem.PMemException)818    def test_write_infoblock_size_unaligned(self):819        """820        Test write_infoblock with align size821        """822        if not self.plib.check_ndctl_subcmd("write-infoblock"):823            self.cancel("Binary does not support write-infoblock")824        region = self.get_default_region()825        self.plib.disable_namespace(region=region)826        self.plib.destroy_namespace(region=region)827        self.plib.create_namespace(region=region, mode='devdax')828        ns_name = self.plib.run_ndctl_list_val(829            self.plib.run_ndctl_list("-N -r %s" % region)[0], 'dev')830        size = self.plib.run_ndctl_list_val(831            self.plib.run_ndctl_list("-N -r %s" % region)[0], 'size')832        self.plib.disable_namespace(namespace=ns_name)833        align = memory.get_page_size()834        size = size - align835        self.write_read_infoblock(ns_name, size=size, align=align)836        try:837            self.plib.enable_namespace(namespace=ns_name)838        except pmem.PMemException:839            self.log.info("Failed as expected")840        else:841            self.log.info(self.plib.run_ndctl_list())842            self.fail("Enabling namespace must have failed")843    @avocado.fail_on(pmem.PMemException)844    def test_sector_write(self):845        """846        Test write on a sector mode device847        """848        region = self.get_default_region()849        self.plib.disable_namespace(region=region)850        self.plib.destroy_namespace(region=region)851        self.plib.create_namespace(region=region, mode='sector',852                                   sector_size='512')853        self.disk = '/dev/%s' % self.plib.run_ndctl_list_val(854            self.plib.run_ndctl_list("-N -r %s" % region)[0], 'blockdev')855        size = self.plib.run_ndctl_list_val(self.plib.run_ndctl_list(856            "-N -r %s" % region)[0], 'size')857        mnt_path = self.params.get('mnt_point', default='/pmemS')858        self.part = partition.Partition(self.disk, mountpoint=mnt_path)859        self.part.mkfs(fstype='xfs', args='-b size=%s -s size=512' %860                       memory.get_page_size())861        if not os.path.exists(mnt_path):862            os.makedirs(mnt_path)863        self.part.mount()864        self.log.info("Test will run on %s", mnt_path)865        fio_job = self.params.get('fio_job', default='sector-fio.job')866        cmd = '%s --directory %s --filename mmap-pmem --size %s %s' % (867            self.build_fio(), mnt_path, size // 2, self.get_data(fio_job))868        if process.system(cmd, ignore_status=True):869            self.fail("FIO mmap workload on fsdax failed")870    @avocado.fail_on(pmem.PMemException)871    def test_fsdax_write(self):872        """873        Test filesystem DAX with a FIO workload874        """875        region = self.get_default_region()876        self.plib.create_namespace(region=region, mode='fsdax')877        self.disk = '/dev/%s' % self.plib.run_ndctl_list_val(878            self.plib.run_ndctl_list("-N -r %s" % region)[0], 'blockdev')879        size = self.plib.run_ndctl_list_val(self.plib.run_ndctl_list(880            "-N -r %s" % region)[0], 'size')881        mnt_path = self.params.get('mnt_point', default='/pmem')882        self.part = partition.Partition(883            self.disk, mountpoint=mnt_path, mount_options='dax')884        self.part.mkfs(fstype='xfs', args='-b size=%s -s size=512 %s' %885                       (memory.get_page_size(), self.reflink))886        if not os.path.exists(mnt_path):887            os.makedirs(mnt_path)888        self.part.mount()889        self.log.info("Test will run on %s", mnt_path)890        fio_job = self.params.get('fio_job', default='ndctl-fio.job')891        cmd = '%s --directory %s --filename mmap-pmem --size %s %s' % (892            self.build_fio(), mnt_path, size // 2, self.get_data(fio_job))893        if process.system(cmd, ignore_status=True):894            self.fail("FIO mmap workload on fsdax failed")895    @avocado.fail_on(pmem.PMemException)896    def test_map_sync(self):897        """898        Test MAP_SYNC flag with sample mmap write899        """900        region = self.get_default_region()901        self.plib.create_namespace(region=region, mode='fsdax')902        self.disk = '/dev/%s' % self.plib.run_ndctl_list_val(903            self.plib.run_ndctl_list("-N -r %s" % region)[0], 'blockdev')904        mnt_path = self.params.get('mnt_point', default='/pmem_map')905        self.part = partition.Partition(906            self.disk, mountpoint=mnt_path, mount_options='dax')907        self.part.mkfs(fstype='xfs', args='-b size=%s -s size=512 %s' %908                       (memory.get_page_size(), self.reflink))909        if not os.path.exists(mnt_path):910            os.makedirs(mnt_path)911        self.part.mount()912        self.log.info("Testing MAP_SYNC on %s", mnt_path)913        src_file = os.path.join(self.teststmpdir, 'map_sync.c')914        shutil.copyfile(self.get_data('map_sync.c'), src_file)915        process.system('gcc %s -o map_sync' % src_file)916        process.system('fallocate -l 64k %s/new_file' % mnt_path)917        if process.system('./map_sync %s/new_file'918                          % mnt_path, ignore_status=True):919            self.fail('Write with MAP_SYNC flag failed')920    @avocado.fail_on(pmem.PMemException)921    def test_devdax_write(self):922        """923        Test device DAX with a daxio binary924        """925        region = self.get_default_region()926        self.plib.create_namespace(region=region, mode='devdax')927        daxdev = "/dev/%s" % self.plib.run_ndctl_list_val(928            self.plib.run_ndctl_list("-N -r %s" % region)[0], 'chardev')929        if process.system(930                "%s -b no -i /dev/urandom -o %s"931                % (self.get_data("daxio.static"), daxdev), ignore_status=True):932            self.fail("DAXIO write on devdax failed")933    @avocado.fail_on(pmem.PMemException)934    def tearDown(self):935        if hasattr(self, 'part') and self.part:936            self.part.unmount()937        if hasattr(self, 'disk') and self.disk:938            self.log.info("Removing the FS meta created on %s", self.disk)939            delete_fs = "dd if=/dev/zero bs=1M count=1024 of=%s" % self.disk940            if process.system(delete_fs, shell=True, ignore_status=True):941                self.fail("Failed to delete filesystem on %s" % self.disk)...pmem_dm.py
Source:pmem_dm.py  
...115    def test(self):116        self.plib.enable_region()117        regions = self.plib.run_ndctl_list('-R')118        self.plib.destroy_namespace(force=True)119        region = self.plib.run_ndctl_list_val(regions[0], 'dev')120        split = self.params.get('split_ns', default=False)121        if len(regions) == 1:122            if self.plib.is_region_legacy(region):123                self.cancel("Cannot create DM with single pmem device")124            if not split:125                self.cancel("Cannot run test without split option enabled")126        if split:127            if self.plib.is_region_legacy(region):128                self.cancel("Cannot split pmem device on legacy hardware")129            size_align = self.get_size_alignval()130            self.log.info("Creating namespace with existing regions")131            for reg_json in regions:132                region = self.plib.run_ndctl_list_val(reg_json, 'dev')133                slot_count = self.plib.get_slot_count(region)134                reg_size = self.plib.run_ndctl_list_val(135                    self.plib.run_ndctl_list('-r %s' % region)[0], 'size')136                namespace_size = reg_size // slot_count137                # Now align the namespace size138                namespace_size = (namespace_size //139                                  size_align) * size_align140                if namespace_size <= size_align:141                    self.log.warn("Skipping namespace size less than pagesize")142                    continue143                for _ in range(0, slot_count):144                    self.plib.create_namespace(145                        region=region, size=namespace_size)146        else:147            self.log.info("Creating namespace with full size")148            for reg_json in regions:149                region = self.plib.run_ndctl_list_val(reg_json, 'dev')150                self.plib.create_namespace(region=region)151        devices = self.plib.run_ndctl_list('-N')152        blk_cmd = ""153        bdev = None154        blk_size1 = 0155        for cnt, dev in enumerate(devices):156            bdev = self.plib.run_ndctl_list_val(dev, 'blockdev')157            bdev = "/dev/%s" % bdev158            blk_size2 = process.system_output(159                "blockdev --getsz %s" % bdev).decode()160            blk_cmd += ' %s %s linear %s 0 "\\\\n"' % (161                blk_size1, blk_size2, bdev)162            blk_size1 += int(blk_size2)163            if cnt == len(devices) - 1:164                break165        dm_cmd = 'echo -e "%s" | dmsetup create linear-pmem' % blk_cmd166        if process.system(dm_cmd, shell=True, sudo=True, ignore_status=True):167            self.fail("Creating DM failed")168        self.log.info("Running FIO on device-mapper")169        dm_disk = "/dev/mapper/linear-pmem"170        self.part = partition.Partition(dm_disk)...pmem_dt_check.py
Source:pmem_dt_check.py  
...119    @avocado.fail_on(pmem.PMemException)120    def test(self):121        self.plib.enable_region()122        regions = self.plib.run_ndctl_list('-R')123        region = self.plib.run_ndctl_list_val(regions[0], 'dev')124        legacy = self.plib.is_region_legacy(region)125        buses = self.plib.run_ndctl_list('-RBN')126        failures = []127        assoc_ref_index = self.get_ref_point_index(legacy=legacy)128        for val in buses:129            region = self.plib.run_ndctl_list_val(val, 'regions')130            sys_id = self.plib.run_ndctl_list_val(region[0], 'dev')131            if legacy:132                # Use namespace level node for legacy h/w133                nss = self.plib.run_ndctl_list_val(region[0], 'namespaces')134                sys_id = self.plib.run_ndctl_list_val(nss[0], 'dev')135            node_path = '/sys/bus/nd/devices/%s/target_node' % sys_id136            if not os.path.exists(node_path):137                # Fallback to numa_node if target_node support does not exist138                node_path = '/sys/bus/nd/devices/%s/numa_node' % sys_id139            node = genio.read_one_line(node_path)140            provider = self.plib.run_ndctl_list_val(val, 'provider')141            if legacy:142                dt_node = str(self.parse_legacy_dt(assoc_ref_index, provider))143            else:144                dt_node = str(self.parse_pmem_dt(assoc_ref_index, provider))145            if node != dt_node:146                failures.append("%s associativity is wrong! "147                                "Exp:%s, Got:%s" % (sys_id, dt_node, node))148            else:149                self.log.info("Working as expected. "150                              "ndctl node: %s, DT node: %s", node, dt_node)151        if failures:152            self.fail(failures)153    @avocado.fail_on(pmem.PMemException)154    def tearDown(self):...Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
