# -*- coding: utf-8 -*- """ tests.support.zfs ~~~~~~~~~~~~~~~~~ ZFS related unit test data structures """ # Import Python libs from __future__ import absolute_import, print_function, unicode_literals # Import salt libs import salt.utils.zfs # Import Salt tests libs from tests.support.mock import MagicMock, patch class ZFSMockData(object): def __init__(self): # property_map mocks self.pmap_exec_zpool = { "retcode": 2, "stdout": "", "stderr": "\n".join( [ "missing property argument", "usage:", ' get [-Hp] [-o "all" | field[,...]] <"all" | property[,...]> ...', "", "the following properties are supported:", "", " PROPERTY EDIT VALUES", "", " allocated NO ", " capacity NO ", " dedupratio NO <1.00x or higher if deduped>", " expandsize NO ", " fragmentation NO ", " free NO ", " freeing NO ", " guid NO ", " health NO ", " leaked NO ", " size NO ", " altroot YES ", " autoexpand YES on | off", " autoreplace YES on | off", " bootfs YES ", " bootsize YES ", " cachefile YES | none", " comment YES ", " dedupditto YES ", " delegation YES on | off", " failmode YES wait | continue | panic", " listsnapshots YES on | off", " readonly YES on | off", " version YES ", " feature@... YES disabled | enabled | active", "", "The feature@ properties must be appended with a feature name.", "See zpool-features(5). ", ] ), } self.pmap_zpool = { "comment": {"edit": True, "type": "str", "values": ""}, "freeing": {"edit": False, "type": "size", "values": ""}, "listsnapshots": {"edit": True, "type": "bool", "values": "on | off"}, "leaked": {"edit": False, "type": "size", "values": ""}, "version": {"edit": True, "type": "numeric", "values": ""}, "write": {"edit": False, "type": "size", "values": ""}, "replace": {"edit": True, "type": "bool", "values": "on | off"}, "delegation": {"edit": True, "type": "bool", "values": "on | off"}, "dedupditto": { "edit": True, "type": "str", "values": "", }, "autoexpand": {"edit": True, "type": "bool", "values": "on | off"}, "alloc": {"edit": False, "type": "size", "values": ""}, "allocated": {"edit": False, "type": "size", "values": ""}, "guid": {"edit": False, "type": "numeric", "values": ""}, "size": {"edit": False, "type": "size", "values": ""}, "cap": {"edit": False, "type": "numeric", "values": ""}, "capacity": {"edit": False, "type": "size", "values": ""}, "capacity-alloc": {"edit": False, "type": "size", "values": ""}, "capacity-free": {"edit": False, "type": "size", "values": ""}, "cachefile": {"edit": True, "type": "str", "values": " | none"}, "cksum": {"edit": False, "type": "numeric", "values": ""}, "bootfs": {"edit": True, "type": "str", "values": ""}, "autoreplace": {"edit": True, "type": "bool", "values": "on | off"}, "bandwidth-read": {"edit": False, "type": "size", "values": ""}, "bandwidth-write": {"edit": False, "type": "size", "values": ""}, "operations-read": {"edit": False, "type": "size", "values": ""}, "operations-write": {"edit": False, "type": "size", "values": ""}, "read": {"edit": False, "type": "size", "values": ""}, "readonly": {"edit": True, "type": "bool", "values": "on | off"}, "dedupratio": { "edit": False, "type": "str", "values": "<1.00x or higher if deduped>", }, "health": {"edit": False, "type": "str", "values": ""}, "feature@": { "edit": True, "type": "str", "values": "disabled | enabled | active", }, "expandsize": {"edit": False, "type": "size", "values": ""}, "listsnaps": {"edit": True, "type": "bool", "values": "on | off"}, "bootsize": {"edit": True, "type": "size", "values": ""}, "free": {"edit": False, "type": "size", "values": ""}, "failmode": { "edit": True, "type": "str", "values": "wait | continue | panic", }, "altroot": {"edit": True, "type": "str", "values": ""}, "expand": {"edit": True, "type": "bool", "values": "on | off"}, "frag": {"edit": False, "type": "str", "values": ""}, "fragmentation": {"edit": False, "type": "str", "values": ""}, } self.pmap_exec_zfs = { "retcode": 2, "stdout": "", "stderr": "\n".join( [ "missing property argument", "usage:", ' get [-crHp] [-d max] [-o "all" | field[,...]]', " [-t type[,...]] [-s source[,...]]", ' <"all" | property[,...]> [filesystem|volume|snapshot|bookmark] ...', "", "The following properties are supported:", "", " PROPERTY EDIT INHERIT VALUES", "", " available NO NO ", " clones NO NO [,...]", " compressratio NO NO <1.00x or higher if compressed>", " creation NO NO ", " defer_destroy NO NO yes | no", " filesystem_count NO NO ", " logicalreferenced NO NO ", " logicalused NO NO ", " mounted NO NO yes | no", " origin NO NO ", " receive_resume_token NO NO ", " refcompressratio NO NO <1.00x or higher if compressed>", " referenced NO NO ", " snapshot_count NO NO ", " type NO NO filesystem | volume | snapshot | bookmark", " used NO NO ", " usedbychildren NO NO ", " usedbydataset NO NO ", " usedbyrefreservation NO NO ", " usedbysnapshots NO NO ", " userrefs NO NO ", " written NO NO ", " aclinherit YES YES discard | noallow | restricted | passthrough | passthrough-x", " aclmode YES YES discard | groupmask | passthrough | restricted", " atime YES YES on | off", " canmount YES NO on | off | noauto", " casesensitivity NO YES sensitive | insensitive | mixed", " checksum YES YES on | off | fletcher2 | fletcher4 | sha256 | sha512 | skein | edonr", " compression YES YES on | off | lzjb | gzip | gzip-[1-9] | zle | lz4", " copies YES YES 1 | 2 | 3", " dedup YES YES on | off | verify | sha256[,verify], sha512[,verify], skein[,verify], edonr,verify", " devices YES YES on | off", " exec YES YES on | off", " filesystem_limit YES NO | none", " logbias YES YES latency | throughput", " mlslabel YES YES ", " mountpoint YES YES | legacy | none", " nbmand YES YES on | off", " normalization NO YES none | formC | formD | formKC | formKD", " primarycache YES YES all | none | metadata", " quota YES NO | none", " readonly YES YES on | off", " recordsize YES YES 512 to 1M, power of 2", " redundant_metadata YES YES all | most", " refquota YES NO | none", " refreservation YES NO | none", " reservation YES NO | none", " secondarycache YES YES all | none | metadata", " setuid YES YES on | off", " sharenfs YES YES on | off | share(1M) options", " sharesmb YES YES on | off | sharemgr(1M) options", " snapdir YES YES hidden | visible", " snapshot_limit YES NO | none", " sync YES YES standard | always | disabled", " utf8only NO YES on | off", " version YES NO 1 | 2 | 3 | 4 | 5 | current", " volblocksize NO YES 512 to 128k, power of 2", " volsize YES NO ", " vscan YES YES on | off", " xattr YES YES on | off", " zoned YES YES on | off", " userused@... NO NO ", " groupused@... NO NO ", " userquota@... YES NO | none", " groupquota@... YES NO | none", " written@ NO NO ", "", "Sizes are specified in bytes with standard units such as K, M, G, etc.", "", "User-defined properties can be specified by using a name containing a colon (:).", "", "The {user|group}{used|quota}@ properties must be appended with", "a user or group specifier of one of these forms:", ' POSIX name (eg: "matt")', ' POSIX id (eg: "126829")', ' SMB name@domain (eg: "matt@sun")', ' SMB SID (eg: "S-1-234-567-89")', ] ), } self.pmap_zfs = { "origin": { "edit": False, "inherit": False, "values": "", "type": "str", }, "setuid": { "edit": True, "inherit": True, "values": "on | off", "type": "bool", }, "referenced": { "edit": False, "inherit": False, "values": "", "type": "size", }, "vscan": { "edit": True, "inherit": True, "values": "on | off", "type": "bool", }, "logicalused": { "edit": False, "inherit": False, "values": "", "type": "size", }, "userrefs": { "edit": False, "inherit": False, "values": "", "type": "numeric", }, "primarycache": { "edit": True, "inherit": True, "values": "all | none | metadata", "type": "str", }, "logbias": { "edit": True, "inherit": True, "values": "latency | throughput", "type": "str", }, "creation": { "edit": False, "inherit": False, "values": "", "type": "str", }, "sync": { "edit": True, "inherit": True, "values": "standard | always | disabled", "type": "str", }, "dedup": { "edit": True, "inherit": True, "values": "on | off | verify | sha256[,verify], sha512[,verify], skein[,verify], edonr,verify", "type": "bool", }, "sharenfs": { "edit": True, "inherit": True, "values": "on | off | share(1m) options", "type": "bool", }, "receive_resume_token": { "edit": False, "inherit": False, "values": "", "type": "str", }, "usedbyrefreservation": { "edit": False, "inherit": False, "values": "", "type": "size", }, "sharesmb": { "edit": True, "inherit": True, "values": "on | off | sharemgr(1m) options", "type": "bool", }, "rdonly": { "edit": True, "inherit": True, "values": "on | off", "type": "bool", }, "reservation": { "edit": True, "inherit": False, "values": " | none", "type": "size", }, "reserv": { "edit": True, "inherit": False, "values": " | none", "type": "size", }, "mountpoint": { "edit": True, "inherit": True, "values": " | legacy | none", "type": "str", }, "casesensitivity": { "edit": False, "inherit": True, "values": "sensitive | insensitive | mixed", "type": "str", }, "utf8only": { "edit": False, "inherit": True, "values": "on | off", "type": "bool", }, "usedbysnapshots": { "edit": False, "inherit": False, "values": "", "type": "size", }, "readonly": { "edit": True, "inherit": True, "values": "on | off", "type": "bool", }, "written@": { "edit": False, "inherit": False, "values": "", "type": "size", }, "avail": { "edit": False, "inherit": False, "values": "", "type": "size", }, "recsize": { "edit": True, "inherit": True, "values": "512 to 1m, power of 2", "type": "str", }, "atime": { "edit": True, "inherit": True, "values": "on | off", "type": "bool", }, "compression": { "edit": True, "inherit": True, "values": "on | off | lzjb | gzip | gzip-[1-9] | zle | lz4", "type": "bool", }, "snapdir": { "edit": True, "inherit": True, "values": "hidden | visible", "type": "str", }, "aclmode": { "edit": True, "inherit": True, "values": "discard | groupmask | passthrough | restricted", "type": "str", }, "zoned": { "edit": True, "inherit": True, "values": "on | off", "type": "bool", }, "copies": { "edit": True, "inherit": True, "values": "1 | 2 | 3", "type": "numeric", }, "snapshot_limit": { "edit": True, "inherit": False, "values": " | none", "type": "numeric", }, "aclinherit": { "edit": True, "inherit": True, "values": "discard | noallow | restricted | passthrough | passthrough-x", "type": "str", }, "compressratio": { "edit": False, "inherit": False, "values": "<1.00x or higher if compressed>", "type": "str", }, "xattr": { "edit": True, "inherit": True, "values": "on | off", "type": "bool", }, "written": { "edit": False, "inherit": False, "values": "", "type": "size", }, "version": { "edit": True, "inherit": False, "values": "1 | 2 | 3 | 4 | 5 | current", "type": "numeric", }, "recordsize": { "edit": True, "inherit": True, "values": "512 to 1m, power of 2", "type": "str", }, "refquota": { "edit": True, "inherit": False, "values": " | none", "type": "size", }, "filesystem_limit": { "edit": True, "inherit": False, "values": " | none", "type": "numeric", }, "lrefer.": { "edit": False, "inherit": False, "values": "", "type": "size", }, "type": { "edit": False, "inherit": False, "values": "filesystem | volume | snapshot | bookmark", "type": "str", }, "secondarycache": { "edit": True, "inherit": True, "values": "all | none | metadata", "type": "str", }, "refer": { "edit": False, "inherit": False, "values": "", "type": "size", }, "available": { "edit": False, "inherit": False, "values": "", "type": "size", }, "used": { "edit": False, "inherit": False, "values": "", "type": "size", }, "exec": { "edit": True, "inherit": True, "values": "on | off", "type": "bool", }, "compress": { "edit": True, "inherit": True, "values": "on | off | lzjb | gzip | gzip-[1-9] | zle | lz4", "type": "bool", }, "volblock": { "edit": False, "inherit": True, "values": "512 to 128k, power of 2", "type": "str", }, "refcompressratio": { "edit": False, "inherit": False, "values": "<1.00x or higher if compressed>", "type": "str", }, "quota": { "edit": True, "inherit": False, "values": " | none", "type": "size", }, "groupquota@": { "edit": True, "inherit": False, "values": " | none", "type": "size", }, "userquota@": { "edit": True, "inherit": False, "values": " | none", "type": "size", }, "snapshot_count": { "edit": False, "inherit": False, "values": "", "type": "numeric", }, "volsize": { "edit": True, "inherit": False, "values": "", "type": "size", }, "clones": { "edit": False, "inherit": False, "values": "[,...]", "type": "str", }, "canmount": { "edit": True, "inherit": False, "values": "on | off | noauto", "type": "bool", }, "mounted": { "edit": False, "inherit": False, "values": "yes | no", "type": "bool_alt", }, "groupused@": { "edit": False, "inherit": False, "values": "", "type": "size", }, "normalization": { "edit": False, "inherit": True, "values": "none | formc | formd | formkc | formkd", "type": "str", }, "usedbychildren": { "edit": False, "inherit": False, "values": "", "type": "size", }, "usedbydataset": { "edit": False, "inherit": False, "values": "", "type": "size", }, "mlslabel": { "edit": True, "inherit": True, "values": "", "type": "str", }, "refreserv": { "edit": True, "inherit": False, "values": " | none", "type": "size", }, "defer_destroy": { "edit": False, "inherit": False, "values": "yes | no", "type": "bool_alt", }, "volblocksize": { "edit": False, "inherit": True, "values": "512 to 128k, power of 2", "type": "str", }, "lused.": { "edit": False, "inherit": False, "values": "", "type": "size", }, "redundant_metadata": { "edit": True, "inherit": True, "values": "all | most", "type": "str", }, "filesystem_count": { "edit": False, "inherit": False, "values": "", "type": "numeric", }, "devices": { "edit": True, "inherit": True, "values": "on | off", "type": "bool", }, "refreservation": { "edit": True, "inherit": False, "values": " | none", "type": "size", }, "userused@": { "edit": False, "inherit": False, "values": "", "type": "size", }, "logicalreferenced": { "edit": False, "inherit": False, "values": "", "type": "size", }, "checksum": { "edit": True, "inherit": True, "values": "on | off | fletcher2 | fletcher4 | sha256 | sha512 | skein | edonr", "type": "bool", }, "nbmand": { "edit": True, "inherit": True, "values": "on | off", "type": "bool", }, } def _from_auto(self, name, value, source="auto"): """ some more complex patching for zfs.from_auto """ with patch.object( salt.utils.zfs, "property_data_zpool", MagicMock(return_value=self.pmap_zpool), ), patch.object( salt.utils.zfs, "property_data_zfs", MagicMock(return_value=self.pmap_zfs) ): return salt.utils.zfs.from_auto(name, value, source) def _from_auto_dict(self, values, source="auto"): """ some more complex patching for zfs.from_auto_dict """ with patch.object( salt.utils.zfs, "property_data_zpool", MagicMock(return_value=self.pmap_zpool), ), patch.object( salt.utils.zfs, "property_data_zfs", MagicMock(return_value=self.pmap_zfs) ): return salt.utils.zfs.from_auto_dict(values, source) def _to_auto(self, name, value, source="auto", convert_to_human=True): """ some more complex patching for zfs.to_auto """ with patch.object( salt.utils.zfs, "property_data_zpool", MagicMock(return_value=self.pmap_zpool), ), patch.object( salt.utils.zfs, "property_data_zfs", MagicMock(return_value=self.pmap_zfs) ): return salt.utils.zfs.to_auto(name, value, source, convert_to_human) def _to_auto_dict(self, values, source="auto", convert_to_human=True): """ some more complex patching for zfs.to_auto_dict """ with patch.object( salt.utils.zfs, "property_data_zpool", MagicMock(return_value=self.pmap_zpool), ), patch.object( salt.utils.zfs, "property_data_zfs", MagicMock(return_value=self.pmap_zfs) ): return salt.utils.zfs.to_auto_dict(values, source, convert_to_human) def get_patched_utils(self): return { "zfs.is_supported": MagicMock(return_value=True), "zfs.has_feature_flags": MagicMock(return_value=True), "zfs.property_data_zpool": MagicMock(return_value=self.pmap_zpool), "zfs.property_data_zfs": MagicMock(return_value=self.pmap_zfs), # NOTE: we make zpool_command and zfs_command a NOOP # these are extensively tested in tests.unit.utils.test_zfs "zfs.zpool_command": MagicMock(return_value="/bin/false"), "zfs.zfs_command": MagicMock(return_value="/bin/false"), # NOTE: from_auto_dict is a special snowflake # internally it calls multiple calls from # salt.utils.zfs but we cannot patch those using # the common methode, __utils__ is not available # so they are direct calls, we do some voodoo here. "zfs.from_auto_dict": self._from_auto_dict, "zfs.from_auto": self._from_auto, "zfs.to_auto_dict": self._to_auto_dict, "zfs.to_auto": self._to_auto, }