From 9db1bdc88bde42878425e5cbbc2ffe25433e6920 Mon Sep 17 00:00:00 2001 From: Glenn Matthews Date: Tue, 17 Feb 2015 14:07:35 -0500 Subject: [PATCH] Removed get_value, set_value, validate_arg in favor of using Python properties --- COT/add_disk.py | 110 ++++++----- COT/add_file.py | 49 ++--- COT/cli.py | 10 +- COT/deploy.py | 130 ++++++------- COT/edit_hardware.py | 254 +++++++++++++------------ COT/edit_product.py | 25 +-- COT/edit_properties.py | 93 ++++------ COT/help.py | 29 +-- COT/info.py | 63 ++++--- COT/inject_config.py | 96 +++++----- COT/submodule.py | 134 ++++++-------- COT/tests/add_disk.py | 155 ++++++++-------- COT/tests/add_file.py | 38 ++-- COT/tests/deploy.py | 55 +++--- COT/tests/edit_hardware.py | 350 +++++++++++++++++------------------ COT/tests/edit_product.py | 37 ++-- COT/tests/edit_properties.py | 55 +++--- COT/tests/info.py | 62 +++---- COT/tests/inject_config.py | 71 ++++--- COT/tests/submodule.py | 19 +- 20 files changed, 889 insertions(+), 946 deletions(-) diff --git a/COT/add_disk.py b/COT/add_disk.py index 82af731..8a85380 100644 --- a/COT/add_disk.py +++ b/COT/add_disk.py @@ -28,70 +28,71 @@ class COTAddDisk(COTSubmodule): """Add or replace a disk in a virtual machine""" def __init__(self, UI): - super(COTAddDisk, self).__init__( - UI, - [ - "DISK_IMAGE", - "PACKAGE", - "output", - "type", - "subtype", - "file_id", - "controller", - "address", - "diskname", - "description", - ]) - - def validate_arg(self, arg, value): - """Check whether it's OK to set the given argument to the given value. - Returns either (True, massaged_value) or (False, reason)""" - valid, value_or_reason = super(COTAddDisk, self).validate_arg(arg, - value) - if not valid or value_or_reason is None: - return valid, value_or_reason - value = value_or_reason - - if arg == "DISK_IMAGE": - if not os.path.exists(value): - return False, ("Specified disk '{0}' does not exist!" - .format(value)) - elif arg == "address": - return self.validate_controller_address(None, value) - elif arg == "controller": - return self.validate_controller_address(value, None) - - return valid, value_or_reason + super(COTAddDisk, self).__init__(UI) + self._disk_image = None + self.type = None + self.subtype = None + self.file_id = None + self._controller = None + self._address = None + self.diskname = None + self.description = None + + @property + def disk_image(self): + return self._disk_image + + @disk_image.setter + def disk_image(self, value): + if not os.path.exists(value): + raise InvalidInputError("Specified disk '{0}' does not exist!" + .format(value)) + self._disk_image = value + + @property + def address(self): + return self._address + + @address.setter + def address(self, value): + logger.info("Setting address to '{0}'".format(value)) + self.validate_controller_address(self.controller, value) + self._address = value + + @property + def controller(self): + return self._controller + + @controller.setter + def controller(self, value): + logger.info("Setting controller to '{0}'".format(value)) + self.validate_controller_address(value, self.address) + self._controller = value def validate_controller_address(self, controller, address): - if controller is not None: - input_value = controller - address = self.get_value("address") - elif address is not None: - input_value = address - controller = self.get_value("controller") - + logger.info("validate_controller_address: {0}, {1}" + .format(controller, address)) if controller is not None and address is not None: + logger.info("Validating controller/address combo") ctrl_addr = address.split(":")[0] disk_addr = address.split(":")[1] if controller == "scsi" and (int(ctrl_addr) > 3 or int(disk_addr) > 15): - return False, "SCSI disk address must be between 0:0 and 3:15" + raise InvalidInputError( + "SCSI disk address must be between 0:0 and 3:15") elif controller == "ide" and (int(ctrl_addr) > 1 or int(disk_addr) > 1): - return False, "IDE disk address must be between 0:0 and 1:1" - - return True, input_value + raise InvalidInputError( + "IDE disk address must be between 0:0 and 1:1") def ready_to_run(self): """Are we ready to go? Returns the tuple (ready, reason)""" - if self.get_value("DISK_IMAGE") is None: + if self.disk_image is None: return False, "DISK_IMAGE is a mandatory argument!" - elif self.get_value("address") is not None: - if self.get_value("controller") is None: - return False, ("When specifying an address you must also " - "specify the controller type") + elif self.address is not None and self.controller is None: + return False, ("When specifying an address you must also " + "specify the controller type") return super(COTAddDisk, self).ready_to_run() def run(self): @@ -99,7 +100,14 @@ def run(self): add_disk_worker(self.vm, UI=self.UI, - **self.args) + DISK_IMAGE=self.disk_image, + type=self.type, + subtype=self.subtype, + file_id=self.file_id, + controller=self.controller, + address=self.address, + diskname=self.diskname, + description=self.description) def create_subparser(self, parent): p = parent.add_parser( diff --git a/COT/add_file.py b/COT/add_file.py index 14fa41a..27d9bce 100644 --- a/COT/add_file.py +++ b/COT/add_file.py @@ -17,7 +17,7 @@ import os.path import logging -from .data_validation import check_for_conflict +from .data_validation import check_for_conflict, InvalidInputError from .submodule import COTSubmodule logger = logging.getLogger(__name__) @@ -27,46 +27,33 @@ class COTAddFile(COTSubmodule): """Add a file (such as a README) to the package.""" def __init__(self, UI): - super(COTAddFile, self).__init__( - UI, - [ - "FILE", - "PACKAGE", - "output", - "file_id" - ]) - - def validate_arg(self, arg, value): - """Check whether it's OK to set the given argument to the given value. - Returns either (True, massaged_value) or (False, reason)""" - valid, value_or_reason = super(COTAddFile, self).validate_arg(arg, - value) - if not valid or value_or_reason is None: - return valid, value_or_reason - value = value_or_reason - - if arg == "FILE": - if not os.path.exists(value): - return False, ("Specified file '{0}' does not exist!" - .format(value)) - - return valid, value_or_reason - - def set_value(self, arg, value): - super(COTAddFile, self).set_value(arg, value) + super(COTAddFile, self).__init__(UI) + self._file = None + self.file_id = None + + @property + def file(self): + return self._file + + @file.setter + def file(self, value): + if not os.path.exists(value): + raise InvalidInputError("Specified file '{0}' does not exist!" + .format(value)) + self._file = value def ready_to_run(self): """Are we ready to go? Returns the tuple (ready, reason)""" - if self.get_value("FILE") is None: + if self.file is None: return False, "FILE is a mandatory argument!" return super(COTAddFile, self).ready_to_run() def run(self): super(COTAddFile, self).run() - FILE = self.get_value("FILE") - file_id = self.get_value("file_id") + FILE = self.file + file_id = self.file_id vm = self.vm filename = os.path.basename(FILE) diff --git a/COT/cli.py b/COT/cli.py index fbfa145..201cfca 100644 --- a/COT/cli.py +++ b/COT/cli.py @@ -358,11 +358,13 @@ def main(self, args): try: # Set mandatory (CAPITALIZED) args first, then optional args for (arg, value) in arg_hash.items(): - if arg[0].isupper(): - args.instance.set_value(arg, value) + if arg[0].isupper() and value is not None: + setattr(args.instance, arg.lower(), value) for (arg, value) in arg_hash.items(): - if not arg[0].isupper() and arg != "instance": - args.instance.set_value(arg, value) + if arg == "instance": + continue + if not arg[0].isupper() and value is not None: + setattr(args.instance, arg, value) args.instance.run() args.instance.finished() except InvalidInputError as e: diff --git a/COT/deploy.py b/COT/deploy.py index 04350ba..3fc64bd 100644 --- a/COT/deploy.py +++ b/COT/deploy.py @@ -21,60 +21,67 @@ from .submodule import COTReadOnlySubmodule from COT.helper_tools import check_call, get_ovftool_version +from COT.data_validation import InvalidInputError logger = logging.getLogger(__name__) class COTDeploy(COTReadOnlySubmodule): - def __init__(self, UI, arg_names=None): - if arg_names is None: - arg_names = [] - arg_names = [ - "PACKAGE", - "HYPERVISOR", - "configuration", - "username", - "password", - "power_on", - "vm_name", - "network_map", - ] + arg_names - super(COTDeploy, self).__init__(UI, arg_names) - self.args["power_on"] = False + def __init__(self, UI): + super(COTDeploy, self).__init__(UI) + # User inputs + self._hypervisor = None + self._configuration = None + self.username = None + self.password = None + self._power_on = False + self.vm_name = None + self.network_map = None + # Internal attributes self.generic_parser = None self.parser = None self.subparsers = None - def validate_arg(self, arg, value): - """Check whether it's OK to set the given argument to the given value. - Returns either (True, massaged_value) or (False, reason)""" - valid, value_or_reason = super(COTDeploy, self).validate_arg(arg, - value) - if not valid or value_or_reason is None: - return valid, value_or_reason - value = value_or_reason - - if arg == "HYPERVISOR": - if value != "esxi": - return False, ("'{0}' is not a supported hypervisor" - .format(value)) - elif arg == 'configuration' and self.vm is not None: + @property + def hypervisor(self): + return self._hypervisor + + @hypervisor.setter + def hypervisor(self, value): + if value != "esxi": + raise InvalidInputError("'{0}' is not a supported hypervisor" + .format(value)) + self._hypervisor = value + + @property + def configuration(self): + return self._configuration + + @configuration.setter + def configuration(self, value): + if self.vm is not None: profiles = self.vm.get_configuration_profile_ids() if value is not None and not (value in profiles): - return False, ("'Configuration '{0}' is not a recognized " - "profile for '{1}'.\nValid options are:\n{2}" - .format(value, self.get_value("PACKAGE"), - "\n".join(profiles))) - elif arg == 'power_on': - if value is not True and value is not False: - return False, "power_on accepts boolean values only" - - return valid, value + raise InvalidInputError( + "'Configuration '{0}' is not a recognized " + "profile for '{1}'.\nValid options are:\n{2}" + .format(value, self.package, "\n".join(profiles))) + self._configuration = value + + @property + def power_on(self): + return self._power_on + + @power_on.setter + def power_on(self, value): + if value is not True and value is not False: + raise InvalidInputError("power_on accepts boolean values only") + self._power_on = value def ready_to_run(self): """Are we ready to go? Returns the tuple (ready, reason)""" - if self.get_value("HYPERVISOR") is None: + if self.hypervisor is None: return False, "HYPERVISOR is a mandatory argument" return super(COTDeploy, self).ready_to_run() @@ -134,19 +141,15 @@ def create_subparser(self, parent): class COTDeployESXi(COTDeploy): def __init__(self, UI): - super(COTDeployESXi, self).__init__( - UI, - [ - "LOCATOR", - "datastore", - "ovftool_args", - ]) - self.args["ovftool_args"] = [] + super(COTDeployESXi, self).__init__(UI) + self.locator = None + self.datastore = None + self.ovftool_args = [] def ready_to_run(self): """Are we ready to go? Returns the tuple (ready, reason)""" - if self.get_value("LOCATOR") is None: + if self.locator is None: return False, "LOCATOR is a mandatory argument" return super(COTDeployESXi, self).ready_to_run() @@ -154,9 +157,9 @@ def run(self): super(COTDeployESXi, self).run() # ensure user provided proper credentials - username = self.get_value("username") - password = self.get_value("password") - LOCATOR = self.get_value("LOCATOR") + username = self.username + password = self.password + LOCATOR = self.locator server = LOCATOR.split("/")[0] if username is None: username = getpass.getuser() @@ -165,7 +168,7 @@ def run(self): target = "vi://" + username + ":" + password + "@" + LOCATOR - ovftool_args = self.get_value("ovftool_args") + ovftool_args = self.ovftool_args # Use shlex to split ovftool_args but respect quoted whitespace if ovftool_args: ovftool_args = shlex.split(ovftool_args) @@ -173,8 +176,8 @@ def run(self): else: ovftool_args = [] - PACKAGE = self.get_value("PACKAGE") - configuration = self.get_value("configuration") + PACKAGE = self.package + configuration = self.configuration vm = self.vm @@ -197,7 +200,7 @@ def run(self): "version is too low to add injectOvfEnv " "option. OVF environment properties will " "be ignored.") - elif not self.get_value("power_on"): + elif not self.power_on: self.UI.confirm_or_die( "When deploying an OVF directly to a vSphere target, " "OVF environment properties can only be made available to " @@ -256,26 +259,23 @@ def run(self): serial_count = serial_count[configuration] # pass network settings on to ovftool - network_map = self.get_value("network_map") - if network_map is not None: - for nm in network_map: + if self.network_map is not None: + for nm in self.network_map: ovftool_args.append("--net:" + nm) # check if user entered a name for the VM - vm_name = self.get_value("vm_name") - if vm_name is not None: - ovftool_args.append("--name=" + vm_name) + if self.vm_name is not None: + ovftool_args.append("--name=" + self.vm_name) # tell ovftool to power on the VM # TODO - if serial port fixup (below) is implemented, # do not power on VM until after serial ports are added. - if self.get_value("power_on"): + if self.power_on: ovftool_args.append("--powerOn") # specify target datastore - datastore = self.get_value("datastore") - if datastore: - ovftool_args.append("--datastore=" + datastore) + if self.datastore is not None: + ovftool_args.append("--datastore=" + self.datastore) # add package and target to the list ovftool_args.append(PACKAGE) diff --git a/COT/edit_hardware.py b/COT/edit_hardware.py index e103f29..4257bdd 100644 --- a/COT/edit_hardware.py +++ b/COT/edit_hardware.py @@ -19,7 +19,7 @@ import re from .data_validation import natural_sort, no_whitespace, mac_address -from .data_validation import non_negative_int, positive_int +from .data_validation import non_negative_int, positive_int, InvalidInputError from .submodule import COTSubmodule logger = logging.getLogger(__name__) @@ -29,101 +29,130 @@ class COTEditHardware(COTSubmodule): """Edit hardware information (CPUs, RAM, NICs, etc.)""" def __init__(self, UI): - super(COTEditHardware, self).__init__( - UI, - [ - "PACKAGE", - "output", - "profiles", - "cpus", - "memory", - "nics", - "nic_type", - "mac_addresses_list", - "nic_networks", - "nic_names", - "serial_ports", - "serial_connectivity", - "scsi_subtype", - "ide_subtype", - "virtual_system_type", - ]) - - # We like to see memory input in the form "4096M" or "4 GB" - MEMORY_REGEXP = r"^\s*(\d+)\s*([mMgG])?[bB]?\s*$" - - def validate_arg(self, arg, value): - """Check whether it's OK to set the given argument to the given value. - Returns either (True, massaged_value) or (False, reason)""" - valid, value_or_reason = super(COTEditHardware, self).validate_arg( - arg, value) - if not valid or value_or_reason is None: - return valid, value_or_reason - value = value_or_reason - + super(COTEditHardware, self).__init__(UI) + self.profiles = None + self._cpus = None + self._memory = None + self._nics = None + self._nic_type = None + self.mac_addresses_list = None + self.nic_networks = None + self.nic_names = None + self._serial_ports = None + self.serial_connectivity = None + self.scsi_subtype = None + self.ide_subtype = None + self.virtual_system_type = None + + @property + def cpus(self): + return self._cpus + + @cpus.setter + def cpus(self, value): + try: + value = int(value) + except ValueError: + raise InvalidInputError("cpus value must be an integer") + if value < 1: + raise InvalidInputError("CPU count must be at least 1") + self.vm.get_platform().validate_cpu_count(value) + self._cpus = value + + @property + def memory(self): + return self._memory + + @memory.setter + def memory(self, value): + value = str(value) + # We like to see memory input in the form "4096M" or "4 GB" + MEMORY_REGEXP = r"^\s*(\d+)\s*([mMgG])?[bB]?\s*$" + match = re.match(MEMORY_REGEXP, value) + if not match: + raise InvalidInputError("Could not parse memory string '{0}'" + .format(value)) + mem_value = int(match.group(1)) + if mem_value <= 0: + raise InvalidInputError("Memory must be greater than zero") + if match.group(2) == 'M' or match.group(2) == 'm': + # default + logger.debug("Memory specified in megabytes") + pass + elif match.group(2) == 'G' or match.group(2) == 'g': + logger.debug("Memory specified in gigabytes - " + "converting to megabytes") + mem_value *= 1024 + else: + # Try to be clever and guess the units + if mem_value <= 64: + logger.warning("Memory units not specified, " + "guessing '{0}' means '{0}GB'" + .format(mem_value)) + mem_value *= 1024 + else: + logger.warning("Memory units not specified, " + "guessing '{0}' means '{0}MB'" + .format(mem_value)) + pass + self.vm.get_platform().validate_memory_amount(mem_value) + self._memory = mem_value + + @property + def nics(self): + return self._nics + + @nics.setter + def nics(self, value): + try: + value = int(value) + except ValueError: + raise InvalidInputError("nics value must be an integer") + self.vm.get_platform().validate_nic_count(value) + self._nics = value + + @property + def nic_type(self): + return self._nic_type + + @nic_type.setter + def nic_type(self, value): + self.vm.get_platform().validate_nic_type(value) + self._nic_type = value + + @property + def serial_ports(self): + return self._serial_ports + + @serial_ports.setter + def serial_ports(self, value): try: - if arg == "cpus": - value = int(value) - if value < 1: - return False, "CPU count must be at least 1" - self.vm.get_platform().validate_cpu_count(value) - elif arg == "memory": - value = str(value) - match = re.match(self.MEMORY_REGEXP, value) - if not match: - return (False, "Could not parse memory string '{0}'" - .format(value)) - mem_value = int(match.group(1)) - if mem_value <= 0: - return False, "Memory must be greater than zero" - if match.group(2) == 'M' or match.group(2) == 'm': - # default - logger.debug("Memory specified in megabytes") - pass - elif match.group(2) == 'G' or match.group(2) == 'g': - logger.debug("Memory specified in gigabytes - " - "converting to megabytes") - mem_value *= 1024 - else: - # Try to be clever and guess the units - if mem_value <= 64: - logger.warning("Memory units not specified, " - "guessing '{0}' means '{0}GB'" - .format(mem_value)) - mem_value *= 1024 - else: - logger.warning("Memory units not specified, " - "guessing '{0}' means '{0}MB'" - .format(mem_value)) - pass - self.vm.get_platform().validate_memory_amount(mem_value) - return True, mem_value - elif arg == "nics": - value = int(value) - self.vm.get_platform().validate_nic_count(value) - elif arg == "nic_type": - self.vm.get_platform().validate_nic_type(value) - elif arg == "serial_ports": - value = int(value) - self.vm.get_platform().validate_serial_count(value) - except ValueError as e: - return False, str(e) - - return valid, value + value = int(value) + except ValueError: + raise InvalidInputError("serial_ports value must be an integer") + self.vm.get_platform().validate_serial_count(value) + self._serial_ports = value def ready_to_run(self): """Are we ready to go? Returns the tuple (ready, reason)""" # Need some work to do! - work_to_do = False - for (key, value) in self.args.items(): - if key == "PACKAGE" or key == "output": - continue - elif value is not None: - work_to_do = True - break - if not work_to_do: + if ( + self.profiles is None and + self.cpus is None and + self.memory is None and + self.nics is None and + self.nic_type is None and + self.mac_addresses_list is None and + self.nic_networks is None and + self.nic_names is None and + self.serial_ports is None and + self.serial_connectivity is None and + self.scsi_subtype is None and + self.ide_subtype is None and + self.virtual_system_type is None + ): return (False, "No work requested! Please specify at least " "one hardware change") return super(COTEditHardware, self).ready_to_run() @@ -131,8 +160,8 @@ def ready_to_run(self): def run(self): super(COTEditHardware, self).run() - profiles = self.get_value("profiles") - virtual_system_type = self.get_value("virtual_system_type") + profiles = self.profiles + virtual_system_type = self.virtual_system_type if profiles is not None and virtual_system_type is not None: self.UI.confirm_or_die( "VirtualSystemType is not filtered by configuration profile. " @@ -161,19 +190,16 @@ def run(self): if virtual_system_type is not None: vm.set_system_type(virtual_system_type) - cpus = self.get_value("cpus") - if cpus is not None: - vm.set_cpu_count(cpus, profiles) + if self.cpus is not None: + vm.set_cpu_count(self.cpus, profiles) - memory = self.get_value("memory") - if memory is not None: - vm.set_memory(memory, profiles) + if self.memory is not None: + vm.set_memory(self.memory, profiles) - nic_type = self.get_value("nic_type") - if nic_type is not None: - vm.set_nic_type(nic_type, profiles) + if self.nic_type is not None: + vm.set_nic_type(self.nic_type, profiles) - nics = self.get_value("nics") + nics = self.nics if nics is not None: nics_dict = vm.get_nic_count(profiles) for (profile, count) in nics_dict.items(): @@ -184,7 +210,7 @@ def run(self): .format(profile, count, (count - nics), nics)) vm.set_nic_count(nics, profiles) - nic_networks = self.get_value("nic_networks") + nic_networks = self.nic_networks if nic_networks is not None: existing_networks = vm.get_network_list() # Convert nic_networks to a set to merge duplicate entries @@ -198,15 +224,13 @@ def run(self): vm.create_network(network, desc) vm.set_nic_networks(nic_networks, profiles) - mac_addresses_list = self.get_value("mac_addresses_list") - if mac_addresses_list is not None: - vm.set_nic_mac_addresses(mac_addresses_list, profiles) + if self.mac_addresses_list is not None: + vm.set_nic_mac_addresses(self.mac_addresses_list, profiles) - nic_names = self.get_value("nic_names") - if nic_names is not None: - vm.set_nic_names(nic_names, profiles) + if self.nic_names is not None: + vm.set_nic_names(self.nic_names, profiles) - serial_ports = self.get_value("serial_ports") + serial_ports = self.serial_ports if serial_ports is not None: serial_dict = vm.get_serial_count(profiles) for (profile, count) in serial_dict.items(): @@ -218,7 +242,7 @@ def run(self): serial_ports)) vm.set_serial_count(serial_ports, profiles) - serial_connectivity = self.get_value("serial_connectivity") + serial_connectivity = self.serial_connectivity if serial_connectivity is not None: serial_dict = vm.get_serial_count(profiles) for (profile, count) in serial_dict.items(): @@ -232,13 +256,11 @@ def run(self): len(serial_connectivity))) vm.set_serial_connectivity(serial_connectivity, profiles) - scsi_subtype = self.get_value("scsi_subtype") - if scsi_subtype is not None: - vm.set_scsi_subtype(scsi_subtype, profiles) + if self.scsi_subtype is not None: + vm.set_scsi_subtype(self.scsi_subtype, profiles) - ide_subtype = self.get_value("ide_subtype") - if ide_subtype is not None: - vm.set_ide_subtype(ide_subtype, profiles) + if self.ide_subtype is not None: + vm.set_ide_subtype(self.ide_subtype, profiles) def create_subparser(self, parent): p = parent.add_parser( diff --git a/COT/edit_product.py b/COT/edit_product.py index 3503af6..7ac1ee9 100644 --- a/COT/edit_product.py +++ b/COT/edit_product.py @@ -25,14 +25,9 @@ class COTEditProduct(COTSubmodule): """Edit product information (short version, long version)""" def __init__(self, UI): - super(COTEditProduct, self).__init__( - UI, - [ - "PACKAGE", - "output", - "version", - "full_version", - ]) + super(COTEditProduct, self).__init__(UI) + self.version = None + self.full_version = None def ready_to_run(self): """Are we ready to go? @@ -43,9 +38,9 @@ def ready_to_run(self): return ready, reason work_to_do = False - if self.get_value("version") is not None: + if self.version is not None: work_to_do = True - elif self.get_value("full_version") is not None: + elif self.full_version is not None: work_to_do = True if not work_to_do: @@ -56,12 +51,10 @@ def ready_to_run(self): def run(self): super(COTEditProduct, self).run() - version = self.get_value("version") - if version is not None: - self.vm.set_short_version(version) - full_version = self.get_value("full_version") - if full_version is not None: - self.vm.set_long_version(full_version) + if self.version is not None: + self.vm.set_short_version(self.version) + if self.full_version is not None: + self.vm.set_long_version(self.full_version) def create_subparser(self, parent): p = parent.add_parser( diff --git a/COT/edit_properties.py b/COT/edit_properties.py index e881d9d..51d4b7f 100644 --- a/COT/edit_properties.py +++ b/COT/edit_properties.py @@ -19,7 +19,7 @@ import textwrap from .submodule import COTSubmodule -from .data_validation import ValueUnsupportedError +from .data_validation import ValueUnsupportedError, InvalidInputError logger = logging.getLogger(__name__) @@ -27,66 +27,49 @@ class COTEditProperties(COTSubmodule): def __init__(self, UI): - super(COTEditProperties, self).__init__( - UI, - [ - "PACKAGE", - "output", - "config_file", - "properties" - ]) - - def validate_arg(self, arg, value): - """Check whether it's OK to set the given argument to the given value. - Returns either (True, massaged_value) or (False, reason)""" - - valid, value_or_reason = super(COTEditProperties, self).validate_arg( - arg, value) - if not valid or value_or_reason is None: - return valid, value_or_reason - value = value_or_reason - - if arg == "config_file": - if not os.path.exists(value): - return False, ("Specified config file {0} does not exist!" - .format(value)) - elif arg == "properties": - for key_value_pair in value: - try: - (k, v) = key_value_pair.split('=', 1) - logger.debug("key: {0} value: {1}".format(k, v)) - if k == '': - raise ValueError() - except ValueError: - return False, ("Invalid property '{0}' - properties " - "must be in 'key=value' form" - .format(key_value_pair)) - - return valid, value_or_reason - - def set_value(self, arg, value): - super(COTEditProperties, self).set_value(arg, value) - if arg == "properties" and value is not None: - self.args[arg] = value - - def ready_to_run(self): - """Are we ready to go? - Returns the tuple (ready, reason)""" - return super(COTEditProperties, self).ready_to_run() + super(COTEditProperties, self).__init__(UI) + self._config_file = None + self._properties = None + + @property + def config_file(self): + return self._config_file + + @config_file.setter + def config_file(self, value): + if not os.path.exists(value): + raise InvalidInputError("Specified config file {0} does not exist!" + .format(value)) + self._config_file = value + + @property + def properties(self): + return self._properties + + @properties.setter + def properties(self, value): + for key_value_pair in value: + try: + (k, v) = key_value_pair.split('=', 1) + logger.debug("key: {0} value: {1}".format(k, v)) + if k == '': + raise ValueError() + except ValueError: + raise InvalidInputError("Invalid property '{0}' - properties " + "must be in 'key=value' form" + .format(key_value_pair)) + self._properties = value def run(self): super(COTEditProperties, self).run() - config_file = self.get_value("config_file") - properties = self.get_value("properties") - vm = self.vm - if config_file is not None: - vm.config_file_to_properties(config_file) + if self.config_file is not None: + vm.config_file_to_properties(self.config_file) - if properties is not None: - for key_value_pair in properties: + if self.properties is not None: + for key_value_pair in self.properties: (key, value) = key_value_pair.split('=', 1) logger.debug("key: {0} value: {1}".format(key, value)) if value == '': @@ -101,7 +84,7 @@ def run(self): # TODO - for new property, prompt for label/descr/type? vm.set_property_value(key, value) - if config_file is None and properties is None: + if self.config_file is None and self.properties is None: # Interactive mode! self.edit_properties_interactive(vm) diff --git a/COT/help.py b/COT/help.py index 4a4db59..d839a3a 100644 --- a/COT/help.py +++ b/COT/help.py @@ -17,6 +17,7 @@ import logging from .submodule import COTGenericSubmodule +from .data_validation import InvalidInputError logger = logging.getLogger(__name__) @@ -24,26 +25,26 @@ class COTHelp(COTGenericSubmodule): """Provide 'help ' syntax""" def __init__(self, UI): - super(COTHelp, self).__init__(UI, ["SUBCOMMAND"]) + super(COTHelp, self).__init__(UI) + self._subcommand = None - def validate_arg(self, arg, value): - valid, value_or_reason = super(COTHelp, self).validate_arg(arg, value) - if not valid or value_or_reason is None: - return valid, value_or_reason - if arg == "SUBCOMMAND": - valid_cmds = sorted(self.UI.subparser_lookup.keys()) - if value not in valid_cmds: - return False, ("Invalid command '{0}' (choose from '{1}')" - .format(value, "', '".join(valid_cmds))) + @property + def subcommand(self): + return self._subcommand - return True, value_or_reason + @subcommand.setter + def subcommand(self, value): + valid_cmds = sorted(self.UI.subparser_lookup.keys()) + if value is not None and value not in valid_cmds: + raise InvalidInputError("Invalid command '{0}' (choose from '{1}')" + .format(value, "', '".join(valid_cmds))) + self._subcommand = value def run(self): super(COTHelp, self).run() - command = self.get_value("SUBCOMMAND") - if command: - subp = self.UI.subparser_lookup[command] + if self.subcommand: + subp = self.UI.subparser_lookup[self.subcommand] subp.print_help() else: self.UI.parser.print_help() diff --git a/COT/info.py b/COT/info.py index 8c69c61..436d7cf 100644 --- a/COT/info.py +++ b/COT/info.py @@ -17,58 +17,61 @@ import logging import os.path -from .submodule import COTReadOnlySubmodule +from .submodule import COTGenericSubmodule from .vm_context_manager import VMContextManager +from .data_validation import InvalidInputError logger = logging.getLogger(__name__) -class COTInfo(COTReadOnlySubmodule): +class COTInfo(COTGenericSubmodule): """Display VM information string""" def __init__(self, UI): - super(COTInfo, self).__init__( - UI, - [ - "PACKAGE_LIST", - "verbosity", - ]) - - def validate_arg(self, arg, value): - valid, value_or_reason = super(COTInfo, self).validate_arg(arg, value) - if not valid or value_or_reason is None: - return valid, value_or_reason - value = value_or_reason - - if arg == "PACKAGE_LIST": - for package in value: - if not os.path.exists(package): - return False, ("Specified package {0} does not exist!" - .format(package)) - elif arg == "verbosity": - if value not in ['brief', 'verbose', None]: - return False, "Verbosity must be 'brief', 'verbose', or None" - - return valid, value_or_reason + super(COTInfo, self).__init__(UI) + self._package_list = None + self._verbosity = None + + @property + def package_list(self): + return self._package_list + + @package_list.setter + def package_list(self, value): + for package in value: + if not os.path.exists(package): + raise InvalidInputError("Specified package {0} does not exist!" + .format(package)) + self._package_list = value + + @property + def verbosity(self): + return self._verbosity + + @verbosity.setter + def verbosity(self, value): + if value not in ['brief', 'verbose', None]: + raise InvalidInputError( + "Verbosity must be 'brief', 'verbose', or None") + self._verbosity = value def ready_to_run(self): """Are we ready to go? Returns the tuple (ready, reason) """ - if not self.get_value("PACKAGE_LIST"): + if not self.package_list: return False, "At least one package must be specified" return super(COTInfo, self).ready_to_run() def run(self): super(COTInfo, self).run() - PACKAGE_LIST = self.get_value("PACKAGE_LIST") - verbosity = self.get_value("verbosity") first = True - for package in PACKAGE_LIST: + for package in self.package_list: if not first: print("") with VMContextManager(package, None) as vm: - print(vm.info_string(self.UI.terminal_width() - 1, verbosity)) + print(vm.info_string(self.UI.terminal_width() - 1, + self.verbosity)) first = False def create_subparser(self, parent): diff --git a/COT/inject_config.py b/COT/inject_config.py index 392db70..81d3af1 100644 --- a/COT/inject_config.py +++ b/COT/inject_config.py @@ -19,7 +19,7 @@ import shutil from .add_disk import add_disk_worker -from .data_validation import ValueUnsupportedError +from .data_validation import ValueUnsupportedError, InvalidInputError from .helper_tools import create_disk_image from .submodule import COTSubmodule @@ -32,48 +32,43 @@ class COTInjectConfig(COTSubmodule): """ def __init__(self, UI): - super(COTInjectConfig, self).__init__( - UI, - [ - "PACKAGE", - "output", - "config_file", - "secondary_config_file", - ]) - - def validate_arg(self, arg, value): - """Check whether it's OK to set the given argument to the given value. - Returns either (True, massaged_value) or (False, reason)""" - valid, value_or_reason = super(COTInjectConfig, self).validate_arg( - arg, value) - if not valid or value_or_reason is None: - return valid, value_or_reason - value = value_or_reason - - if self.vm: - platform = self.vm.get_platform() - else: - platform = None - - if arg == "config_file": - value = str(value) - if not os.path.exists(value): - return False, ("Primary config file {0} does not exist!" - .format(value)) - if platform and not platform.CONFIG_TEXT_FILE: - return (False, - "Configuration file not supported for platform {0}" - .format(platform.__name__)) - elif arg == "secondary_config_file": - value = str(value) - if not os.path.exists(value): - return False, ("Secondary config file {0} does not exist!" - .format(value)) - if platform and not platform.SECONDARY_CONFIG_TEXT_FILE: - return (False, "Secondary configuration file not supported " - "for platform {0}".format(platform.__name__)) - - return valid, value + super(COTInjectConfig, self).__init__(UI) + self._config_file = None + self._secondary_config_file = None + + @property + def config_file(self): + return self._config_file + + @config_file.setter + def config_file(self, value): + value = str(value) + if not os.path.exists(value): + raise InvalidInputError("Primary config file {0} does not exist!" + .format(value)) + platform = self.vm.get_platform() + if not platform.CONFIG_TEXT_FILE: + raise InvalidInputError( + "Configuration file not supported for platform {0}" + .format(platform.__name__)) + self._config_file = value + + @property + def secondary_config_file(self): + return self._secondary_config_file + + @secondary_config_file.setter + def secondary_config_file(self, value): + value = str(value) + if not os.path.exists(value): + raise InvalidInputError("Secondary config file {0} does not exist!" + .format(value)) + platform = self.vm.get_platform() + if not platform.SECONDARY_CONFIG_TEXT_FILE: + raise InvalidInputError( + "Secondary configuration file not supported for platform {0}" + .format(platform.__name__)) + self._secondary_config_file = value def ready_to_run(self): """Are we ready to go? @@ -81,9 +76,9 @@ def ready_to_run(self): # Need some work to do! work_to_do = False - if self.get_value("config_file") is not None: + if self.config_file is not None: work_to_do = True - elif self.get_value("secondary_config_file") is not None: + elif self.secondary_config_file is not None: work_to_do = True if not work_to_do: @@ -97,9 +92,6 @@ def run(self): platform = vm.get_platform() - config_file = self.get_value("config_file") - secondary_config_file = self.get_value("secondary_config_file") - # Find the disk drive where the config should be injected # First, look for any previously-injected config disk to overwrite: if platform.BOOTSTRAP_DISK_TYPE == 'cdrom': @@ -130,14 +122,14 @@ def run(self): # Copy config file(s) to per-platform name in working directory config_files = [] - if config_file: + if self.config_file: dest = os.path.join(vm.working_dir, platform.CONFIG_TEXT_FILE) - shutil.copy(config_file, dest) + shutil.copy(self.config_file, dest) config_files.append(dest) - if secondary_config_file: + if self.secondary_config_file: dest = os.path.join(vm.working_dir, platform.SECONDARY_CONFIG_TEXT_FILE) - shutil.copy(secondary_config_file, dest) + shutil.copy(self.secondary_config_file, dest) config_files.append(dest) # Package the config files into a disk image diff --git a/COT/submodule.py b/COT/submodule.py index b5e3245..4e460b5 100644 --- a/COT/submodule.py +++ b/COT/submodule.py @@ -26,54 +26,13 @@ class COTGenericSubmodule(object): """Abstract interface for COT command submodules.""" - def __init__(self, UI, arg_names): - self.args = {} - for name in arg_names: - self.args[name] = None + def __init__(self, UI): self.vm = None self.UI = UI - def validate_arg(self, arg, value): - """Check whether it's OK to set the given argument to the given value. - Returns either (True, massaged_value) or (False, reason)""" - if arg not in self.args.keys(): - return False, "unrecognized argument '{0}'".format(arg) - # Generic input validation common across all submodules - if arg == "PACKAGE": - if not os.path.exists(value): - return False, ("Specified package {0} does not exist!" - .format(value)) - - return True, value - - def set_value(self, arg, value): - """Set the given argument to the given value""" - valid, value_or_reason = self.validate_arg(arg, value) - if not valid: - raise InvalidInputError(value_or_reason) - else: - value = value_or_reason - - if arg == "PACKAGE" and self.vm is not None: - # Delete existing VM before child class (below) creates a new one - self.vm.destroy() - - self.args[arg] = value - - def get_value(self, arg): - """Get the current value of the given arg""" - value = self.args.get(arg, None) - - return value - def ready_to_run(self): """Are we ready to go? Returns the tuple (ready, reason)""" - # do any subclass-specific work here, then call super() - - if "PACKAGE" in self.args.keys() and not self.get_value("PACKAGE"): - return False, "PACKAGE is a mandatory argument!" - return True, "Ready to go!" def run(self): @@ -97,53 +56,82 @@ def create_subparser(self, parent): class COTReadOnlySubmodule(COTGenericSubmodule): - "Class for submodules that do not modify the OVF, such as 'info'" + "Class for submodules that do not modify the OVF, such as 'deploy'" + + def __init__(self, UI): + super(COTReadOnlySubmodule, self).__init__(UI) + self._package = None - def set_value(self, arg, value): - super(COTReadOnlySubmodule, self).set_value(arg, value) + @property + def package(self): + return self._package - if arg == "PACKAGE": + @package.setter + def package(self, value): + if value is not None and not os.path.exists(value): + raise InvalidInputError("Specified package {0} does not exist!" + .format(value)) + if self.vm is not None: + self.vm.destroy() + self.vm = None + if value is not None: self.vm = VMFactory.create(value, None) + self._package = value + + def ready_to_run(self): + if self.package is None: + return False, "PACKAGE is a mandatory argument!" + return super(COTReadOnlySubmodule, self).ready_to_run() class COTSubmodule(COTGenericSubmodule): "Class for submodules that read and write the OVF" - def __init__(self, UI, arg_names): - super(COTSubmodule, self).__init__( - UI, ["PACKAGE", "output"] + arg_names) + def __init__(self, UI): + super(COTSubmodule, self).__init__(UI) + self._package = None # Default to an unspecified output rather than no output - self.args["output"] = "" + self._output = "" - def validate_arg(self, arg, value): - valid, value = super(COTSubmodule, self).validate_arg(arg, value) - if not valid: - return valid, value + @property + def package(self): + return self._package - if arg == "output": - if (value is not None and value != self.get_value(arg) and - os.path.exists(value)): - self.UI.confirm_or_die("Overwrite existing file {0}?" - .format(value)) - - return True, value - - def set_value(self, arg, value): - super(COTSubmodule, self).set_value(arg, value) + @package.setter + def package(self, value): + if value is not None and not os.path.exists(value): + raise InvalidInputError("Specified package {0} does not exist!" + .format(value)) + if self.vm is not None: + self.vm.destroy() + self.vm = None + if value is not None: + self.vm = VMFactory.create(value, self.output) + self._package = value + + @property + def output(self): + return self._output + + @output.setter + def output(self, value): + if value and value != self._output and os.path.exists(value): + self.UI.confirm_or_die("Overwrite existing file {0}?" + .format(value)) + self._output = value + if self.vm is not None: + self.vm.set_output_file(value) - if arg == "PACKAGE": - self.vm = VMFactory.create(value, self.get_value("output")) - elif arg == "output": - if self.vm is not None: - self.vm.set_output_file(value) + def ready_to_run(self): + if self.package is None: + return False, "PACKAGE is a mandatory argument!" + return super(COTSubmodule, self).ready_to_run() def run(self): super(COTSubmodule, self).run() - if "output" in self.args.keys() and "PACKAGE" in self.args.keys(): - output = self.get_value("output") - if not output: - self.set_value("output", self.get_value("PACKAGE")) + if not self.output: + self.output = self.package # Do the work now... def finished(self): diff --git a/COT/tests/add_disk.py b/COT/tests/add_disk.py index ec3be0f..31c80e1 100644 --- a/COT/tests/add_disk.py +++ b/COT/tests/add_disk.py @@ -33,34 +33,34 @@ def setUp(self): """Test case setup function called automatically prior to each test.""" super(TestCOTAddDisk, self).setUp() self.instance = COTAddDisk(UI()) - self.instance.set_value("output", self.temp_file) + self.instance.output = self.temp_file self.new_vmdk = os.path.join(os.path.dirname(__file__), "blank.vmdk") def test_readiness(self): """Test ready_to_run() under various combinations of parameters.""" - self.instance.set_value("PACKAGE", self.input_ovf) + self.instance.package = self.input_ovf ready, reason = self.instance.ready_to_run() self.assertFalse(ready) self.assertTrue(re.search("DISK_IMAGE is a mandatory", reason)) self.assertRaises(InvalidInputError, self.instance.run) - self.instance.set_value("DISK_IMAGE", self.new_vmdk) + self.instance.disk_image = self.new_vmdk ready, reason = self.instance.ready_to_run() self.assertTrue(ready) - self.instance.set_value("address", "1:0") + self.instance.address = "1:0" ready, reason = self.instance.ready_to_run() self.assertFalse(ready) self.assertTrue(re.search("controller", reason)) self.assertRaises(InvalidInputError, self.instance.run) - self.instance.set_value("controller", "ide") + self.instance.controller = "ide" ready, reason = self.instance.ready_to_run() self.assertTrue(ready) # address without controller is not allowed, # but controller without address is OK - self.instance.set_value("address", None) + self.instance.address = None ready, reason = self.instance.ready_to_run() self.assertTrue(ready) @@ -68,12 +68,12 @@ def test_conflicting_args_1(self): """Test conflicting arguments are detected and rejected""" # TODO - it would be nice to detect this in ready_to_run() # rather than run() - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("DISK_IMAGE", self.new_vmdk) + self.instance.package = self.input_ovf + self.instance.disk_image = self.new_vmdk # file2 exists and is mapped to IDE 1:0 but we request IDE 1:1 - self.instance.set_value("controller", "ide") - self.instance.set_value("address", "1:1") - self.instance.set_value("file_id", "file2") + self.instance.controller = "ide" + self.instance.address = "1:1" + self.instance.file_id = "file2" self.assertRaises(ValueMismatchError, self.instance.run) self.assertLogged(**self.TYPE_NOT_SPECIFIED_GUESS_HARDDISK) @@ -81,12 +81,11 @@ def test_conflicting_args_2(self): """Test conflicting arguments are detected and rejected""" # TODO - it would be nice to detect this in ready_to_run() # rather than run() - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("DISK_IMAGE", - os.path.join(os.path.dirname(__file__), - "input.iso")) + self.instance.package = self.input_ovf + self.instance.disk_image = os.path.join(os.path.dirname(__file__), + "input.iso") # ovf contains input.iso but we're asking it to overwrite input.vmdk - self.instance.set_value("file_id", "vmdisk1") + self.instance.file_id = "vmdisk1" self.assertRaises(ValueMismatchError, self.instance.run) self.assertLogged(**self.TYPE_NOT_SPECIFIED_GUESS_CDROM) @@ -94,21 +93,20 @@ def test_conflicting_args_3(self): """Test conflicting arguments are detected and rejected""" # TODO - it would be nice to detect this in ready_to_run() # rather than run() - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("DISK_IMAGE", - os.path.join(os.path.dirname(__file__), - "input.vmdk")) + self.instance.package = self.input_ovf + self.instance.disk_image = os.path.join(os.path.dirname(__file__), + "input.vmdk") # ovf contains input.vmdk but we're asking it to overwrite input.iso - self.instance.set_value("controller", "ide") - self.instance.set_value("address", "1:0") + self.instance.controller = "ide" + self.instance.address = "1:0" self.assertRaises(ValueMismatchError, self.instance.run) self.assertLogged(**self.TYPE_NOT_SPECIFIED_GUESS_HARDDISK) def test_new_hard_disk(self): """Test adding a new hard disk to the OVF.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("DISK_IMAGE", self.new_vmdk) + self.instance.package = self.input_ovf + self.instance.disk_image = self.new_vmdk self.instance.run() self.assertLogged(**self.TYPE_NOT_SPECIFIED_GUESS_HARDDISK) self.assertLogged(**self.CONTROLLER_NOT_SPECIFIED_GUESS_IDE) @@ -146,10 +144,10 @@ def test_new_hard_disk(self): def test_new_hard_disk_and_explicit_controller(self): """Test adding a hard disk to an explicitly new SCSI controller.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("DISK_IMAGE", self.new_vmdk) - self.instance.set_value("controller", "scsi") - self.instance.set_value("address", "1:0") + self.instance.package = self.input_ovf + self.instance.disk_image = self.new_vmdk + self.instance.controller = "scsi" + self.instance.address = "1:0" self.instance.run() self.assertLogged(**self.TYPE_NOT_SPECIFIED_GUESS_HARDDISK) self.instance.finished() @@ -196,8 +194,8 @@ def test_new_hard_disk_and_automatic_controller(self): """Add a new hard disk and create an IDE controller automatically.""" # Since the primary IDE0 controller is already full in the IOSv OVF, # COT will need to automatically create IDE1 controller - self.instance.set_value("PACKAGE", self.iosv_ovf) - self.instance.set_value("DISK_IMAGE", self.new_vmdk) + self.instance.package = self.iosv_ovf + self.instance.disk_image = self.new_vmdk self.instance.run() self.assertLogged(**self.TYPE_NOT_SPECIFIED_GUESS_HARDDISK) self.assertLogged(**self.CONTROLLER_NOT_SPECIFIED_GUESS_IDE) @@ -243,8 +241,8 @@ def test_new_hard_disk_and_automatic_controller(self): def test_new_hard_disk_v09(self): """Test adding a disk to a version 0.9 OVF.""" - self.instance.set_value("PACKAGE", self.v09_ovf) - self.instance.set_value("DISK_IMAGE", self.new_vmdk) + self.instance.package = self.v09_ovf + self.instance.disk_image = self.new_vmdk self.instance.run() self.assertLogged(**self.TYPE_NOT_SPECIFIED_GUESS_HARDDISK) self.assertLogged(**self.CONTROLLER_NOT_SPECIFIED_GUESS_IDE) @@ -279,8 +277,8 @@ def test_new_hard_disk_v09(self): def test_new_hard_disk_v20_vbox(self): """Test adding a new hard disk to a v2.0 OVF from VirtualBox""" - self.instance.set_value("PACKAGE", self.v20_vbox_ovf) - self.instance.set_value("DISK_IMAGE", self.new_vmdk) + self.instance.package = self.v20_vbox_ovf + self.instance.disk_image = self.new_vmdk self.instance.run() self.assertLogged(**self.TYPE_NOT_SPECIFIED_GUESS_HARDDISK) self.assertLogged(**self.CONTROLLER_NOT_SPECIFIED_GUESS_IDE) @@ -293,11 +291,11 @@ def test_new_hard_disk_v20_vbox(self): def test_overwrite_hard_disk_fileid(self): """Overwrite an existing disk by specifying matching file-id.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("DISK_IMAGE", self.new_vmdk) - self.instance.set_value("file_id", 'file1') + self.instance.package = self.input_ovf + self.instance.disk_image = self.new_vmdk + self.instance.file_id = 'file1' # For coverage's sake, let's change the controller subtype too - self.instance.set_value("subtype", "virtio") + self.instance.subtype = "virtio" self.instance.run() self.assertLogged(**self.TYPE_NOT_SPECIFIED_GUESS_HARDDISK) self.assertLogged(**self.OVERWRITING_FILE) @@ -337,10 +335,10 @@ def test_overwrite_hard_disk_fileid(self): def test_overwrite_hard_disk_address(self): """Overwrite an existing disk by setting matching controller address""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("DISK_IMAGE", self.new_vmdk) - self.instance.set_value("controller", 'scsi') - self.instance.set_value("address", "0:0") + self.instance.package = self.input_ovf + self.instance.disk_image = self.new_vmdk + self.instance.controller = 'scsi' + self.instance.address = "0:0" self.instance.run() self.assertLogged(**self.TYPE_NOT_SPECIFIED_GUESS_HARDDISK) self.assertLogged(**self.OVERWRITING_FILE) @@ -379,9 +377,9 @@ def test_disk_conversion(self): new_qcow2 = os.path.join(self.temp_dir, "new.qcow2") # Make it a small file to keep the test fast create_disk_image(new_qcow2, capacity="16M") - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("DISK_IMAGE", new_qcow2) - self.instance.set_value("controller", 'scsi') + self.instance.package = self.input_ovf + self.instance.disk_image = new_qcow2 + self.instance.controller = 'scsi' self.instance.run() self.assertLogged(**self.TYPE_NOT_SPECIFIED_GUESS_HARDDISK) self.instance.finished() @@ -423,8 +421,8 @@ def test_disk_conversion_and_replacement(self): new_qcow2 = os.path.join(self.temp_dir, "input.qcow2") # Keep it small! create_disk_image(new_qcow2, capacity="16M") - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("DISK_IMAGE", new_qcow2) + self.instance.package = self.input_ovf + self.instance.disk_image = new_qcow2 self.instance.run() self.assertLogged(**self.TYPE_NOT_SPECIFIED_GUESS_HARDDISK) self.assertLogged(**self.OVERWRITING_FILE) @@ -455,8 +453,8 @@ def test_add_disk_no_existing(self): """Add a disk to an OVF that doesn't currently have any. Verify correct creation of various OVF sub-sections. """ - self.instance.set_value("PACKAGE", self.minimal_ovf) - self.instance.set_value("DISK_IMAGE", self.new_vmdk) + self.instance.package = self.minimal_ovf + self.instance.disk_image = self.new_vmdk self.instance.run() self.assertLogged(**self.TYPE_NOT_SPECIFIED_GUESS_HARDDISK) self.assertLogged(**self.CONTROLLER_NOT_SPECIFIED_GUESS_IDE) @@ -502,11 +500,11 @@ def test_add_disk_no_existing(self): """.format(blank_size=self.FILE_SIZE['blank.vmdk'])) def test_add_cdrom_to_existing_controller(self): - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("DISK_IMAGE", self.new_vmdk) - self.instance.set_value("type", "cdrom") - self.instance.set_value("controller", "scsi") - self.instance.set_value("address", "0:1") + self.instance.package = self.input_ovf + self.instance.disk_image = self.new_vmdk + self.instance.type = "cdrom" + self.instance.controller = "scsi" + self.instance.address = "0:1" self.instance.run() self.instance.finished() self.check_diff(""" @@ -529,8 +527,8 @@ def test_add_cdrom_to_existing_controller(self): def test_add_disk_no_room(self): # iosv.ovf already has two disks. Add a third disk... - self.instance.set_value("PACKAGE", self.iosv_ovf) - self.instance.set_value("DISK_IMAGE", self.new_vmdk) + self.instance.package = self.iosv_ovf + self.instance.disk_image = self.new_vmdk self.instance.run() self.assertLogged(**self.TYPE_NOT_SPECIFIED_GUESS_HARDDISK) self.assertLogged(**self.CONTROLLER_NOT_SPECIFIED_GUESS_IDE) @@ -575,10 +573,9 @@ def test_add_disk_no_room(self): """.format(blank_size=self.FILE_SIZE['blank.vmdk'])) # Add a fourth disk... - self.instance.set_value("PACKAGE", self.temp_file) - self.instance.set_value("DISK_IMAGE", - os.path.join(os.path.dirname(__file__), - 'input.iso')) + self.instance.package = self.temp_file + self.instance.disk_image = os.path.join(os.path.dirname(__file__), + 'input.iso') self.instance.run() self.assertLogged(**self.TYPE_NOT_SPECIFIED_GUESS_CDROM) self.assertLogged(**self.CONTROLLER_NOT_SPECIFIED_GUESS_IDE) @@ -635,18 +632,17 @@ def test_add_disk_no_room(self): # Keep it small! create_disk_image(new_qcow2, capacity="16M") # Try to add a fifth disk - IDE controllers are full! - self.instance.set_value("PACKAGE", self.temp_file) - self.instance.set_value("DISK_IMAGE", new_qcow2) + self.instance.package = self.temp_file + self.instance.disk_image = new_qcow2 self.assertRaises(ValueTooHighError, self.instance.run) self.assertLogged(**self.TYPE_NOT_SPECIFIED_GUESS_HARDDISK) self.assertLogged(**self.CONTROLLER_NOT_SPECIFIED_GUESS_IDE) def test_overwrite_implicit_file_id(self): """file_id defaults to filename if not set.""" - self.instance.set_value("PACKAGE", self.invalid_ovf) - self.instance.set_value("DISK_IMAGE", - os.path.join(os.path.dirname(__file__), - "input.vmdk")) + self.instance.package = self.invalid_ovf + self.instance.disk_image = os.path.join(os.path.dirname(__file__), + "input.vmdk") self.instance.run() self.assertLogged(**self.UNRECOGNIZED_PRODUCT_CLASS) self.assertLogged(**self.NONEXISTENT_FILE) @@ -678,10 +674,10 @@ def test_overwrite_implicit_file_id(self): self.validate_output_with_ovftool = False def test_overwrite_disk_with_bad_host_resource(self): - self.instance.set_value("PACKAGE", self.invalid_ovf) - self.instance.set_value("DISK_IMAGE", self.new_vmdk) - self.instance.set_value("controller", "ide") - self.instance.set_value("address", "0:0") + self.instance.package = self.invalid_ovf + self.instance.disk_image = self.new_vmdk + self.instance.controller = "ide" + self.instance.address = "0:0" with self.assertRaises(ValueUnsupportedError) as cm: self.instance.run() self.assertTrue(re.search("HostResource", str(cm.exception))) @@ -692,28 +688,27 @@ def test_overwrite_disk_with_bad_host_resource(self): msg="Unrecognized HostResource format") def test_overwrite_disk_with_bad_parent_by_file(self): - self.instance.set_value("PACKAGE", self.invalid_ovf) - self.instance.set_value("DISK_IMAGE", - os.path.join(os.path.dirname(__file__), - 'input.iso')) + self.instance.package = self.invalid_ovf + self.instance.disk_image = os.path.join(os.path.dirname(__file__), + 'input.iso') self.assertRaises(LookupError, self.instance.run) self.assertLogged(**self.UNRECOGNIZED_PRODUCT_CLASS) self.assertLogged(**self.NONEXISTENT_FILE) self.assertLogged(**self.TYPE_NOT_SPECIFIED_GUESS_CDROM) def test_overwrite_disk_with_bad_parent_by_fileid(self): - self.instance.set_value("PACKAGE", self.invalid_ovf) - self.instance.set_value("DISK_IMAGE", self.new_vmdk) - self.instance.set_value("file_id", "input.iso") + self.instance.package = self.invalid_ovf + self.instance.disk_image = self.new_vmdk + self.instance.file_id = "input.iso" self.assertRaises(LookupError, self.instance.run) self.assertLogged(**self.UNRECOGNIZED_PRODUCT_CLASS) self.assertLogged(**self.NONEXISTENT_FILE) self.assertLogged(**self.TYPE_NOT_SPECIFIED_GUESS_HARDDISK) def test_overwrite_disk_with_bad_fileref(self): - self.instance.set_value("PACKAGE", self.invalid_ovf) - self.instance.set_value("DISK_IMAGE", self.new_vmdk) - self.instance.set_value("file_id", "flash2") + self.instance.package = self.invalid_ovf + self.instance.disk_image = self.new_vmdk + self.instance.file_id = "flash2" self.assertRaises(LookupError, self.instance.run) self.assertLogged(**self.UNRECOGNIZED_PRODUCT_CLASS) self.assertLogged(**self.NONEXISTENT_FILE) diff --git a/COT/tests/add_file.py b/COT/tests/add_file.py index dc2f6df..484ba27 100644 --- a/COT/tests/add_file.py +++ b/COT/tests/add_file.py @@ -28,7 +28,7 @@ def setUp(self): """Test case setup function called automatically prior to each test.""" super(TestCOTAddFile, self).setUp() self.instance = COTAddFile(UI()) - self.instance.set_value("output", self.temp_file) + self.instance.output = self.temp_file def test_readiness(self): """Test ready_to_run() under various combinations of parameters.""" @@ -37,20 +37,20 @@ def test_readiness(self): self.assertEqual("FILE is a mandatory argument!", reason) self.assertRaises(InvalidInputError, self.instance.run) - self.instance.set_value("FILE", self.iosv_ovf) + self.instance.file = self.iosv_ovf ready, reason = self.instance.ready_to_run() self.assertFalse(ready) self.assertEqual("PACKAGE is a mandatory argument!", reason) self.assertRaises(InvalidInputError, self.instance.run) - self.instance.set_value("PACKAGE", self.input_ovf) + self.instance.package = self.input_ovf ready, reason = self.instance.ready_to_run() self.assertTrue(ready) def test_add_file(self): """Basic file addition""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("FILE", self.iosv_ovf) + self.instance.package = self.input_ovf + self.instance.file = self.iosv_ovf self.instance.run() self.instance.finished() self.check_diff(""" @@ -62,9 +62,9 @@ def test_add_file(self): def test_add_file_with_id(self): """Add a file with explicit 'file_id' argument.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("FILE", self.iosv_ovf) - self.instance.set_value("file_id", "myfile") + self.instance.package = self.input_ovf + self.instance.file = self.iosv_ovf + self.instance.file_id = "myfile" self.instance.run() self.instance.finished() self.check_diff(""" @@ -75,9 +75,9 @@ def test_add_file_with_id(self): ovf_size=os.path.getsize(self.iosv_ovf))) def test_overwrite_file(self): - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("FILE", os.path.join( - os.path.dirname(__file__), 'input.iso')) + self.instance.package = self.input_ovf + self.instance.file = os.path.join( + os.path.dirname(__file__), 'input.iso') self.instance.run() self.assertLogged(**self.OVERWRITING_FILE) self.instance.finished() @@ -85,12 +85,12 @@ def test_overwrite_file(self): def test_add_file_then_change_to_disk(self): """Add a disk as a file, then make it a proper disk.""" - self.instance.set_value("PACKAGE", self.minimal_ovf) + self.instance.package = self.minimal_ovf intermediate_ovf = os.path.join(self.temp_dir, "mid.ovf") - self.instance.set_value("output", intermediate_ovf) + self.instance.output = intermediate_ovf disk_file = os.path.join(os.path.dirname(__file__), "blank.vmdk") - self.instance.set_value("FILE", disk_file) - self.instance.set_value("file_id", "mydisk") + self.instance.file = disk_file + self.instance.file_id = "mydisk" self.instance.run() self.instance.finished() self.check_diff(file1=self.minimal_ovf, @@ -106,10 +106,10 @@ def test_add_file_then_change_to_disk(self): from COT.add_disk import COTAddDisk ad = COTAddDisk(UI()) - ad.set_value("PACKAGE", intermediate_ovf) - ad.set_value("output", self.temp_file) - ad.set_value("DISK_IMAGE", disk_file) - ad.set_value("file_id", "mydisk") + ad.package = intermediate_ovf + ad.output = self.temp_file + ad.disk_image = disk_file + ad.file_id = "mydisk" ad.run() self.assertLogged(**self.TYPE_NOT_SPECIFIED_GUESS_HARDDISK) self.assertLogged(**self.CONTROLLER_NOT_SPECIFIED_GUESS_IDE) diff --git a/COT/tests/deploy.py b/COT/tests/deploy.py index a31d4b7..f0cceca 100644 --- a/COT/tests/deploy.py +++ b/COT/tests/deploy.py @@ -36,7 +36,7 @@ def setUp(self): "Test case setup function called automatically prior to each test" super(TestCOTDeploy, self).setUp() self.instance = COTDeploy(UI()) - self.instance.set_value("PACKAGE", self.input_ovf) + self.instance.package = self.input_ovf def test_not_ready_with_no_args(self): ready, reason = self.instance.ready_to_run() @@ -45,12 +45,12 @@ def test_not_ready_with_no_args(self): self.assertRaises(InvalidInputError, self.instance.run) def test_invalid_args(self): - self.assertRaises(InvalidInputError, - self.instance.set_value, "HYPERVISOR", "frobozz") - self.assertRaises(InvalidInputError, - self.instance.set_value, "configuration", "") - self.assertRaises(InvalidInputError, - self.instance.set_value, "configuration", "X") + with self.assertRaises(InvalidInputError): + self.instance.hypervisor = "frobozz" + with self.assertRaises(InvalidInputError): + self.instance.configuration = "" + with self.assertRaises(InvalidInputError): + self.instance.configuration = "X" class TestCOTDeployESXi(COT_UT): @@ -88,8 +88,8 @@ def setUp(self): "Test case setup function called automatically prior to each test" super(TestCOTDeployESXi, self).setUp() self.instance = COTDeployESXi(UI()) - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("HYPERVISOR", 'esxi') + self.instance.package = self.input_ovf + self.instance.hypervisor = 'esxi' # Stub out check_call so that we don't actually need ovftool self._check_call = COT.deploy.check_call self.last_argv = [] @@ -116,16 +116,16 @@ def test_not_ready_with_no_args(self): self.assertRaises(InvalidInputError, self.instance.run) def test_invalid_args(self): - self.assertRaises(InvalidInputError, - self.instance.set_value, "configuration", "") - self.assertRaises(InvalidInputError, - self.instance.set_value, "configuration", "X") - self.assertRaises(InvalidInputError, - self.instance.set_value, "power_on", "frobozz") + with self.assertRaises(InvalidInputError): + self.instance.configuration = "" + with self.assertRaises(InvalidInputError): + self.instance.configuration = "X" + with self.assertRaises(InvalidInputError): + self.instance.power_on = "frobozz" def test_ovftool_args_basic(self): "Test that ovftool is called with the expected arguments" - self.instance.set_value("LOCATOR", "localhost") + self.instance.locator = "localhost" self.instance.run() self.assertEqual([ 'ovftool', @@ -138,16 +138,15 @@ def test_ovftool_args_basic(self): def test_ovftool_args_advanced(self): "Test that ovftool is called with the expected arguments" - self.instance.set_value("LOCATOR", "localhost/host/foo") - self.instance.set_value("datastore", "datastore1") - self.instance.set_value("configuration", "2CPU-2GB-1NIC") - self.instance.set_value("vm_name", "myVM") - self.instance.set_value("power_on", True) - self.instance.set_value("ovftool_args", - "--overwrite --vService:'A B=C D'") - self.instance.set_value("username", "u") - self.instance.set_value("password", "p") - self.instance.set_value("network_map", ["VM Network=VM Network"]) + self.instance.locator = "localhost/host/foo" + self.instance.datastore = "datastore1" + self.instance.configuration = "2CPU-2GB-1NIC" + self.instance.vm_name = "myVM" + self.instance.power_on = True + self.instance.ovftool_args = "--overwrite --vService:'A B=C D'" + self.instance.username = "u" + self.instance.password = "p" + self.instance.network_map = ["VM Network=VM Network"] self.instance.run() self.assertEqual([ @@ -171,8 +170,8 @@ def test_ovftool_vsphere_env_fixup(self): # This is tested by test_ovftool_args_basic() above. # With 4.0.0 and power_on, we fixup when deploying to vSphere: - self.instance.set_value("LOCATOR", "vsphere") - self.instance.set_value("power_on", True) + self.instance.locator = "vsphere" + self.instance.power_on = True self.instance.run() self.assertEqual([ 'ovftool', diff --git a/COT/tests/edit_hardware.py b/COT/tests/edit_hardware.py index 1ee1850..562e1c0 100644 --- a/COT/tests/edit_hardware.py +++ b/COT/tests/edit_hardware.py @@ -42,11 +42,11 @@ def setUp(self): """Test case setup function called automatically prior to each test""" super(TestCOTEditHardware, self).setUp() self.instance = COTEditHardware(UI()) - self.instance.set_value("output", self.temp_file) + self.instance.output = self.temp_file def test_not_ready_with_no_args(self): """Test ready_to_run() behavior.""" - self.instance.set_value("PACKAGE", self.input_ovf) + self.instance.package = self.input_ovf ready, reason = self.instance.ready_to_run() self.assertEqual(ready, False) self.assertTrue(re.search("No work requested", reason)) @@ -54,68 +54,68 @@ def test_not_ready_with_no_args(self): def test_valid_args(self): """Verify that various valid args are accepted and stored.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("cpus", "1") - self.assertEqual(self.instance.get_value("cpus"), 1) - self.instance.set_value("memory", "1GB") - self.assertEqual(self.instance.get_value("memory"), 1024) - self.instance.set_value("memory", "2g") - self.assertEqual(self.instance.get_value("memory"), 2048) - self.instance.set_value("memory", "256M") - self.assertEqual(self.instance.get_value("memory"), 256) - self.instance.set_value("memory", "1024") + self.instance.package = self.input_ovf + self.instance.cpus = "1" + self.assertEqual(self.instance.cpus, 1) + self.instance.memory = "1GB" + self.assertEqual(self.instance.memory, 1024) + self.instance.memory = "2g" + self.assertEqual(self.instance.memory, 2048) + self.instance.memory = "256M" + self.assertEqual(self.instance.memory, 256) + self.instance.memory = "1024" self.assertLogged(**self.MEMORY_UNIT_GUESS) - self.assertEqual(self.instance.get_value("memory"), 1024) - self.instance.set_value("nics", 1) - self.assertEqual(self.instance.get_value("nics"), 1) - self.instance.set_value("serial_ports", 1) - self.assertEqual(self.instance.get_value("serial_ports"), 1) + self.assertEqual(self.instance.memory, 1024) + self.instance.nics = 1 + self.assertEqual(self.instance.nics, 1) + self.instance.serial_ports = 1 + self.assertEqual(self.instance.serial_ports, 1) def test_invalid_always_args(self): """Verify that various values are always invalid.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.assertRaises(InvalidInputError, - self.instance.set_value, "cpus", 0) - self.assertRaises(InvalidInputError, - self.instance.set_value, "cpus", "a") - self.assertRaises(InvalidInputError, - self.instance.set_value, "memory", 0) - self.assertRaises(InvalidInputError, - self.instance.set_value, "memory", "GB") - self.assertRaises(InvalidInputError, - self.instance.set_value, "nics", -1) - self.assertRaises(InvalidInputError, - self.instance.set_value, "nics", "b") - self.assertRaises(InvalidInputError, - self.instance.set_value, "serial_ports", -1) - self.assertRaises(InvalidInputError, - self.instance.set_value, "serial_ports", "c") + self.instance.package = self.input_ovf + with self.assertRaises(InvalidInputError): + self.instance.cpus = 0 + with self.assertRaises(InvalidInputError): + self.instance.cpus = "a" + with self.assertRaises(InvalidInputError): + self.instance.memory = 0 + with self.assertRaises(InvalidInputError): + self.instance.memory = "GB" + with self.assertRaises(InvalidInputError): + self.instance.nics = -1 + with self.assertRaises(InvalidInputError): + self.instance.nics = "b" + with self.assertRaises(InvalidInputError): + self.instance.serial_ports = -1 + with self.assertRaises(InvalidInputError): + self.instance.serial_ports = "c" def test_valid_by_platform(self): """Verify that some input values' validity depends on platform.""" - self.instance.set_value("PACKAGE", self.input_ovf) + self.instance.package = self.input_ovf # IOSv only supports 1 vCPU and up to 3 GB of RAM self.instance.vm.platform = IOSv - self.assertRaises(InvalidInputError, - self.instance.set_value, "cpus", 2) - self.assertRaises(InvalidInputError, - self.instance.set_value, "memory", "4GB") + with self.assertRaises(InvalidInputError): + self.instance.cpus = 2 + with self.assertRaises(InvalidInputError): + self.instance.memory = "4GB" # ...but IOSXRv supports up to 8 CPUs and 3-8 GB of RAM self.instance.vm.platform = IOSXRv - self.instance.set_value("cpus", 2) - self.instance.set_value("cpus", 8) - self.assertRaises(InvalidInputError, - self.instance.set_value, "cpus", 9) - self.instance.set_value("memory", "4") + self.instance.cpus = 2 + self.instance.cpus = 8 + with self.assertRaises(InvalidInputError): + self.instance.cpus = 9 + self.instance.memory = "4" self.assertLogged(**self.MEMORY_UNIT_GUESS) - self.instance.set_value("memory", "8GB") - self.assertRaises(InvalidInputError, - self.instance.set_value, "memory", "9GB") + self.instance.memory = "8GB" + with self.assertRaises(InvalidInputError): + self.instance.memory = "9GB" def test_set_system_type_single(self): """Set the VirtualSystemType to a single value""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("virtual_system_type", ['vmx-09']) + self.instance.package = self.input_ovf + self.instance.virtual_system_type = ['vmx-09'] self.instance.run() self.instance.finished() self.check_diff(""" @@ -127,13 +127,12 @@ def test_set_system_type_single(self): def test_set_system_type_list(self): """Set the VirtualSystemType to a list of values.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value( - "virtual_system_type", - ['vmx-07', 'vmx-08', 'vmx-09', 'Cisco:Internal:VMCloud-01']) + self.instance.package = self.input_ovf + self.instance.virtual_system_type = \ + ['vmx-07', 'vmx-08', 'vmx-09', 'Cisco:Internal:VMCloud-01'] # 'profiles' will be ignored in this case, # as VirtualSystemType is not filtered by profile - self.instance.set_value("profiles", ['2CPU-2GB-1NIC']) + self.instance.profiles = ['2CPU-2GB-1NIC'] self.instance.run() # TODO - catch warning logger message that should be generated # due to profiles being ignored. @@ -148,8 +147,8 @@ def test_set_system_type_list(self): def test_set_system_type_no_existing(self): """Add a VirtualSystemType to an OVF that doesn't have any.""" - self.instance.set_value("PACKAGE", self.minimal_ovf) - self.instance.set_value("virtual_system_type", ['vmx-07', 'vmx-08']) + self.instance.package = self.minimal_ovf + self.instance.virtual_system_type = ['vmx-07', 'vmx-08'] self.instance.run() self.instance.finished() self.check_diff(file1=self.minimal_ovf, @@ -172,9 +171,9 @@ def test_set_system_type_no_existing(self): def test_set_cpus_one_profile(self): """Change the number of CPUs under a specific profile""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("cpus", 8) - self.instance.set_value("profiles", ['2CPU-2GB-1NIC']) + self.instance.package = self.input_ovf + self.instance.cpus = 8 + self.instance.profiles = ['2CPU-2GB-1NIC'] self.instance.run() self.instance.finished() self.check_diff(""" @@ -190,9 +189,9 @@ def test_set_cpus_one_profile(self): def test_set_cpus_merge_profiles(self): """Change # CPUs under one profile to match another profile.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("cpus", 4) - self.instance.set_value("profiles", ['2CPU-2GB-1NIC']) + self.instance.package = self.input_ovf + self.instance.cpus = 4 + self.instance.profiles = ['2CPU-2GB-1NIC'] self.instance.run() self.instance.finished() self.check_diff(""" @@ -213,8 +212,8 @@ def test_set_cpus_merge_profiles(self): def test_set_cpus_all_profiles(self): """Change value under all profiles, merging a group of Items.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("cpus", 1) + self.instance.package = self.input_ovf + self.instance.cpus = 1 self.instance.run() self.instance.finished() self.check_diff(""" @@ -242,8 +241,8 @@ def test_set_cpus_all_profiles(self): def test_set_cpus_no_existing(self): """Create a CPU definition in an OVF that doesn't have one.""" - self.instance.set_value("PACKAGE", self.minimal_ovf) - self.instance.set_value("cpus", 1) + self.instance.package = self.minimal_ovf + self.instance.cpus = 1 self.instance.run() self.assertLogged(**self.NEW_HW_FROM_SCRATCH) self.instance.finished() @@ -268,10 +267,10 @@ def test_set_cpus_no_existing(self): def test_set_memory_one_profile(self): """Set memory allocation under one profile.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("memory", 3072) + self.instance.package = self.input_ovf + self.instance.memory = 3072 self.assertLogged(**self.MEMORY_UNIT_GUESS) - self.instance.set_value("profiles", ['2CPU-2GB-1NIC']) + self.instance.profiles = ['2CPU-2GB-1NIC'] self.instance.run() self.instance.finished() self.check_diff(""" @@ -287,8 +286,8 @@ def test_set_memory_one_profile(self): def test_set_memory_all_profiles(self): """Set memory allocation under one profile.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("memory", "3072M") + self.instance.package = self.input_ovf + self.instance.memory = "3072M" self.instance.run() self.instance.finished() self.check_diff(""" @@ -320,8 +319,8 @@ def test_set_memory_all_profiles(self): def test_set_memory_no_existing(self): """Create a RAM definition in an OVF that doesn't have one""" - self.instance.set_value("PACKAGE", self.minimal_ovf) - self.instance.set_value("memory", "4GB") + self.instance.package = self.minimal_ovf + self.instance.memory = "4GB" self.instance.run() self.assertLogged(**self.NEW_HW_FROM_SCRATCH) self.instance.finished() @@ -346,9 +345,9 @@ def test_set_memory_no_existing(self): def test_set_nic_type_one_profile(self): """Set NIC hardware type under a single profile.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("profiles", ['4CPU-4GB-3NIC']) - self.instance.set_value("nic_type", "E1000") + self.instance.package = self.input_ovf + self.instance.profiles = ['4CPU-4GB-3NIC'] + self.instance.nic_type = "E1000" self.instance.run() self.instance.finished() # This requires cloning the "default" NIC under instance 11 @@ -393,8 +392,8 @@ def test_set_nic_type_one_profile(self): def test_set_nic_type_all_profiles(self): """Change NIC hardware type under all profiles""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("nic_type", "virtio") + self.instance.package = self.input_ovf + self.instance.nic_type = "virtio" self.instance.run() self.instance.finished() self.check_diff(""" @@ -434,8 +433,8 @@ def test_set_nic_type_all_profiles(self): def test_set_nic_type_no_existing(self): """Set NIC hardware type for an OVF with no NICs (no-op)""" - self.instance.set_value("PACKAGE", self.minimal_ovf) - self.instance.set_value("nic_type", "virtio") + self.instance.package = self.minimal_ovf + self.instance.nic_type = "virtio" self.instance.run() self.assertLogged(**self.NO_ITEMS_NO_WORK) self.instance.finished() @@ -443,9 +442,9 @@ def test_set_nic_type_no_existing(self): def test_set_nic_count_merge_profiles(self): """Add NICs that already exist under one profile to another.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("nics", 3) - self.instance.set_value("profiles", ['2CPU-2GB-1NIC']) + self.instance.package = self.input_ovf + self.instance.nics = 3 + self.instance.profiles = ['2CPU-2GB-1NIC'] self.instance.run() self.instance.finished() self.check_diff(""" @@ -462,9 +461,9 @@ def test_set_nic_count_merge_profiles(self): def test_set_nic_count_create_new_one_profile(self): """"Create a new NIC under a single profile.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("nics", '4') - self.instance.set_value("profiles", ['4CPU-4GB-3NIC']) + self.instance.package = self.input_ovf + self.instance.nics = '4' + self.instance.profiles = ['4CPU-4GB-3NIC'] self.instance.run() self.instance.finished() self.check_diff(""" @@ -485,9 +484,9 @@ def test_set_nic_count_create_new_one_profile(self): def test_set_nic_count_delete_nics(self): """Set NIC count to a lower value, deleting some NICs.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("nics", 0) - self.instance.set_value("profiles", ['1CPU-1GB-1NIC']) + self.instance.package = self.input_ovf + self.instance.nics = 0 + self.instance.profiles = ['1CPU-1GB-1NIC'] self.instance.run() self.instance.finished() self.check_diff(""" @@ -501,9 +500,9 @@ def test_set_nic_network_one_profile(self): """Create a new network and map a NIC to it under a single profile.""" # Create a new network and map to it under one profile # This involves splitting the existing NIC into two items - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("nic_networks", ['UT']) - self.instance.set_value("profiles", ['2CPU-2GB-1NIC']) + self.instance.package = self.input_ovf + self.instance.nic_networks = ['UT'] + self.instance.profiles = ['2CPU-2GB-1NIC'] self.instance.run() self.instance.finished() self.check_diff(""" @@ -530,8 +529,8 @@ def test_set_nic_network_one_profile(self): def test_set_nic_network_all_profiles(self): """Test changing NIC network mapping across all profiles.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("nic_networks", ['UT', 'UT', 'UT']) + self.instance.package = self.input_ovf + self.instance.nic_networks = ['UT', 'UT', 'UT'] self.instance.run() self.instance.finished() self.check_diff(""" @@ -564,8 +563,8 @@ def test_set_nic_network_list_expansion(self): """Specify fewer networks than NICs to test implicit NIC assignment. Remaining NICs get the last network in the list. """ - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("nic_networks", ['UT1', 'UT2']) + self.instance.package = self.input_ovf + self.instance.nic_networks = ['UT1', 'UT2'] self.instance.run() self.instance.finished() self.check_diff(""" @@ -599,8 +598,8 @@ def test_set_nic_network_list_expansion(self): def test_set_nic_mac_address_single_all_profiles(self): """Set a single MAC address on all NICs on all profiles.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("mac_addresses_list", ['10:20:30:40:50:60']) + self.instance.package = self.input_ovf + self.instance.mac_addresses_list = ['10:20:30:40:50:60'] self.instance.run() self.instance.finished() self.check_diff(""" @@ -619,10 +618,9 @@ def test_set_nic_mac_address_single_all_profiles(self): def test_set_nic_mac_addresses_list_all_profiles(self): """Set a sequence of MAC addresses for all profiles.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value( - "mac_addresses_list", - ['10:20:30:40:50:60', '01:02:03:04:05:06', 'ab:cd:ef:00:00:00']) + self.instance.package = self.input_ovf + self.instance.mac_addresses_list = \ + ['10:20:30:40:50:60', '01:02:03:04:05:06', 'ab:cd:ef:00:00:00'] self.instance.run() self.instance.finished() self.check_diff(""" @@ -641,8 +639,8 @@ def test_set_nic_mac_addresses_list_all_profiles(self): def test_set_nic_name_list_exact(self): """Set a list of NIC names identical in length to the number of NICs""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("nic_names", ['foo', 'bar', 'baz']) + self.instance.package = self.input_ovf + self.instance.nic_names = ['foo', 'bar', 'baz'] self.instance.run() self.instance.finished() self.check_diff(""" @@ -667,8 +665,8 @@ def test_set_nic_name_list_exact(self): def test_set_nic_name_list_extra(self): """Set a list of NIC names that's longer than needed.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("nic_names", ['foo', 'bar', 'baz', 'bat']) + self.instance.package = self.input_ovf + self.instance.nic_names = ['foo', 'bar', 'baz', 'bat'] self.instance.run() self.assertLogged(levelname="ERROR", msg="not all ElementName values were used") @@ -695,8 +693,8 @@ def test_set_nic_name_list_extra(self): def test_set_nic_name_list_short(self): """Set a list of NIC names that's shorter than needed.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("nic_names", ['foo', 'bar']) + self.instance.package = self.input_ovf + self.instance.nic_names = ['foo', 'bar'] self.instance.run() self.instance.finished() self.check_diff(""" @@ -721,8 +719,8 @@ def test_set_nic_name_list_short(self): def test_set_nic_name_pattern(self): """Set NIC names based on a pattern""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("nic_names", ['eth{0}']) + self.instance.package = self.input_ovf + self.instance.nic_names = ['eth{0}'] self.instance.run() self.instance.finished() self.check_diff(""" @@ -747,8 +745,8 @@ def test_set_nic_name_pattern(self): def test_set_nic_name_list_pattern(self): """Set NIC names based on a constant plus a pattern""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("nic_names", ['foo', 'eth{10}']) + self.instance.package = self.input_ovf + self.instance.nic_names = ['foo', 'eth{10}'] self.instance.run() self.instance.finished() self.check_diff(""" @@ -773,12 +771,11 @@ def test_set_nic_name_list_pattern(self): def test_set_nic_kitchen_sink_all_profiles(self): """Test changing many NIC properties at once under all profiles.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("nic_type", 'e1000') - self.instance.set_value("nic_networks", ['UT1', 'UT2', 'UT3']) - self.instance.set_value( - "mac_addresses_list", - ['00:00:00:00:00:01', '11:22:33:44:55:66', 'fe:fd:fc:fb:fa:f9']) + self.instance.package = self.input_ovf + self.instance.nic_type = 'e1000' + self.instance.nic_networks = ['UT1', 'UT2', 'UT3'] + self.instance.mac_addresses_list = \ + ['00:00:00:00:00:01', '11:22:33:44:55:66', 'fe:fd:fc:fb:fa:f9'] self.instance.run() self.instance.finished() self.check_diff(""" @@ -845,10 +842,10 @@ def test_set_nic_kitchen_sink_all_profiles(self): def test_set_nic_kitchen_sink_one_profile(self): """Test changing many NIC properties at once under one profile.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("profiles", ['4CPU-4GB-3NIC']) - self.instance.set_value("nics", 4) - self.instance.set_value("nic_networks", ['UT']) + self.instance.package = self.input_ovf + self.instance.profiles = ['4CPU-4GB-3NIC'] + self.instance.nics = 4 + self.instance.nic_networks = ['UT'] self.instance.run() self.instance.finished() self.check_diff(""" @@ -900,10 +897,10 @@ def test_set_nic_kitchen_sink_one_profile(self): def test_set_nic_kitchen_sink_no_existing(self): """Define NIC in an OVF that previously had none.""" - self.instance.set_value("PACKAGE", self.minimal_ovf) - self.instance.set_value("nics", 1) - self.instance.set_value("nic_networks", ['testme']) - self.instance.set_value("mac_addresses_list", ['12:34:56:78:9a:bc']) + self.instance.package = self.minimal_ovf + self.instance.nics = 1 + self.instance.nic_networks = ['testme'] + self.instance.mac_addresses_list = ['12:34:56:78:9a:bc'] self.instance.run() self.assertLogged(**self.NEW_HW_FROM_SCRATCH) self.instance.finished() @@ -936,9 +933,9 @@ def test_set_nic_kitchen_sink_no_existing(self): def test_set_serial_count_delete_one_profile(self): """Remove a shared serial port from one profile only.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("profiles", ['2CPU-2GB-1NIC']) - self.instance.set_value("serial_ports", 1) + self.instance.package = self.input_ovf + self.instance.profiles = ['2CPU-2GB-1NIC'] + self.instance.serial_ports = 1 self.instance.run() self.instance.finished() self.check_diff(""" @@ -951,8 +948,8 @@ def test_set_serial_count_delete_one_profile(self): def test_set_serial_count_delete_all_profiles(self): """Remove a serial port across all profiles.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("serial_ports", 1) + self.instance.package = self.input_ovf + self.instance.serial_ports = 1 self.instance.run() self.instance.finished() self.check_diff(""" @@ -970,8 +967,8 @@ def test_set_serial_count_delete_all_profiles(self): def test_set_serial_count_create_all_profiles(self): """Create a serial port under all profiles.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("serial_ports", 3) + self.instance.package = self.input_ovf + self.instance.serial_ports = 3 self.instance.run() self.instance.finished() self.check_diff(""" @@ -989,8 +986,8 @@ def test_set_serial_count_create_all_profiles(self): def test_set_serial_count_no_existing(self): """Create a serial port in an OVF that had none.""" - self.instance.set_value("PACKAGE", self.minimal_ovf) - self.instance.set_value("serial_ports", 1) + self.instance.package = self.minimal_ovf + self.instance.serial_ports = 1 self.instance.run() self.assertLogged(**self.NEW_HW_FROM_SCRATCH) self.instance.finished() @@ -1014,9 +1011,8 @@ def test_set_serial_count_no_existing(self): def test_set_serial_connectivity_one_port_all_profiles(self): """Set serial connectivity for one port under all profiles.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("serial_connectivity", - ['telnet://localhost:22001']) + self.instance.package = self.input_ovf + self.instance.serial_connectivity = ['telnet://localhost:22001'] self.instance.run() self.instance.finished() self.check_diff(""" @@ -1027,10 +1023,9 @@ def test_set_serial_connectivity_one_port_all_profiles(self): def test_set_serial_connectivity_two_ports_all_profiles(self): """Set serial connectivity for multiple ports across all profiles.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("serial_connectivity", - ['telnet://localhost:22001', - 'telnet://localhost:22002']) + self.instance.package = self.input_ovf + self.instance.serial_connectivity = \ + ['telnet://localhost:22001', 'telnet://localhost:22002'] self.instance.run() self.instance.finished() self.check_diff(""" @@ -1045,11 +1040,10 @@ def test_set_serial_connectivity_two_ports_all_profiles(self): def test_serial_create_kitchen_sink(self): """Create a serial port and set connectivity in one pass""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("serial_ports", '3') - self.instance.set_value( - "serial_connectivity", - ['telnet://foo:1', 'telnet://foo:2', 'telnet://foo:3']) + self.instance.package = self.input_ovf + self.instance.serial_ports = '3' + self.instance.serial_connectivity = \ + ['telnet://foo:1', 'telnet://foo:2', 'telnet://foo:3'] self.instance.run() self.instance.finished() self.check_diff(""" @@ -1076,9 +1070,9 @@ def test_serial_create_kitchen_sink(self): def test_serial_delete_kitchen_sink(self): """Delete a serial port and set connectivity in one pass""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("serial_ports", 1) - self.instance.set_value("serial_connectivity", ['telnet://bar:22']) + self.instance.package = self.input_ovf + self.instance.serial_ports = 1 + self.instance.serial_connectivity = ['telnet://bar:22'] self.instance.run() self.instance.finished() self.check_diff(""" @@ -1100,8 +1094,8 @@ def test_serial_delete_kitchen_sink(self): def test_set_scsi_subtype_all_profiles(self): """Set SCSI controller subtype under all profiles.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("scsi_subtype", "virtio") + self.instance.package = self.input_ovf + self.instance.scsi_subtype = "virtio" self.instance.run() self.instance.finished() self.check_diff(""" @@ -1113,8 +1107,8 @@ def test_set_scsi_subtype_all_profiles(self): def test_clear_scsi_subtype_all_profiles(self): """Clear SCSI controller subtype under all profiles.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("scsi_subtype", "") + self.instance.package = self.input_ovf + self.instance.scsi_subtype = "" self.instance.run() self.instance.finished() self.check_diff(""" @@ -1125,9 +1119,9 @@ def test_clear_scsi_subtype_all_profiles(self): def test_set_scsi_subtype_one_profile(self): """Set SCSI controller subtype under a single profile.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("scsi_subtype", "virtio") - self.instance.set_value("profiles", ['4CPU-4GB-3NIC']) + self.instance.package = self.input_ovf + self.instance.scsi_subtype = "virtio" + self.instance.profiles = ['4CPU-4GB-3NIC'] self.instance.run() self.instance.finished() # This requires creating a new variant of the SCSI controller @@ -1147,8 +1141,8 @@ def test_set_scsi_subtype_one_profile(self): def test_set_scsi_subtype_no_existing(self): """Set SCSI controller subtype for an OVF with none (no-op)""" - self.instance.set_value("PACKAGE", self.minimal_ovf) - self.instance.set_value("scsi_subtype", "virtio") + self.instance.package = self.minimal_ovf + self.instance.scsi_subtype = "virtio" self.instance.run() self.assertLogged(**self.NO_ITEMS_NO_WORK) self.instance.finished() @@ -1156,8 +1150,8 @@ def test_set_scsi_subtype_no_existing(self): def test_set_ide_subtype_all_profiles(self): """Set IDE controller subtype across all profiles.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("ide_subtype", "virtio") + self.instance.package = self.input_ovf + self.instance.ide_subtype = "virtio" self.instance.run() self.instance.finished() # Since there is no pre-existing subtype, we just create it @@ -1174,9 +1168,9 @@ def test_set_ide_subtype_all_profiles(self): def test_set_ide_subtype_one_profile(self): """Set IDE controller subtype under a single profile.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("ide_subtype", "virtio") - self.instance.set_value("profiles", ['4CPU-4GB-3NIC']) + self.instance.package = self.input_ovf + self.instance.ide_subtype = "virtio" + self.instance.profiles = ['4CPU-4GB-3NIC'] self.instance.run() self.instance.finished() # Here we have to create new controllers under this profile @@ -1207,8 +1201,8 @@ def test_set_ide_subtype_one_profile(self): def test_set_ide_subtype_no_existing(self): """Set IDE controller subtype for an OVF with none (no-op)""" - self.instance.set_value("PACKAGE", self.minimal_ovf) - self.instance.set_value("ide_subtype", "virtio") + self.instance.package = self.minimal_ovf + self.instance.ide_subtype = "virtio" self.instance.run() self.assertLogged(**self.NO_ITEMS_NO_WORK) self.instance.finished() @@ -1216,9 +1210,9 @@ def test_set_ide_subtype_no_existing(self): def test_create_profile_inherit_default(self): """Create a new profile that's identical to the default one.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("profiles", ['UT']) - self.instance.set_value("cpus", 1) + self.instance.package = self.input_ovf + self.instance.profiles = ['UT'] + self.instance.cpus = 1 self.instance.run() self.instance.finished() self.check_diff(""" @@ -1232,9 +1226,9 @@ def test_create_profile_inherit_default(self): def test_create_new_profile(self): """Create a new profile with new values.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("profiles", ['UT']) - self.instance.set_value("cpus", 8) + self.instance.package = self.input_ovf + self.instance.profiles = ['UT'] + self.instance.cpus = 8 self.instance.run() self.instance.finished() self.check_diff(""" @@ -1260,9 +1254,9 @@ def test_create_new_profile(self): def test_create_two_profiles(self): """Create two profiles at once.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("profiles", ['UT', 'UT2']) - self.instance.set_value("memory", 8192) + self.instance.package = self.input_ovf + self.instance.profiles = ['UT', 'UT2'] + self.instance.memory = 8192 self.assertLogged(**self.MEMORY_UNIT_GUESS) self.instance.run() self.instance.finished() @@ -1292,9 +1286,9 @@ def test_create_two_profiles(self): def test_create_profile_no_existing(self): """Add a profile to an OVF that doesn't have any.""" - self.instance.set_value("PACKAGE", self.minimal_ovf) - self.instance.set_value("profiles", ['UT']) - self.instance.set_value("nic_networks", ["VM Network"]) + self.instance.package = self.minimal_ovf + self.instance.profiles = ['UT'] + self.instance.nic_networks = ["VM Network"] self.instance.run() self.assertLogged(levelname="ERROR", msg="not all Connection values were used") diff --git a/COT/tests/edit_product.py b/COT/tests/edit_product.py index e1a091f..ee656d0 100644 --- a/COT/tests/edit_product.py +++ b/COT/tests/edit_product.py @@ -28,7 +28,7 @@ def setUp(self): """Test case setup function called automatically prior to each test""" super(TestCOTEditProduct, self).setUp() self.instance = COTEditProduct(UI()) - self.instance.set_value("output", self.temp_file) + self.instance.output = self.temp_file def test_readiness(self): """Test ready_to_run() under various combinations of parameters.""" @@ -37,22 +37,22 @@ def test_readiness(self): self.assertEqual("PACKAGE is a mandatory argument!", reason) self.assertRaises(InvalidInputError, self.instance.run) - self.instance.set_value("PACKAGE", self.input_ovf) + self.instance.package = self.input_ovf ready, reason = self.instance.ready_to_run() self.assertFalse(ready) self.assertTrue(re.search("nothing to do", reason)) self.assertRaises(InvalidInputError, self.instance.run) - self.instance.set_value("version", "X") + self.instance.version = "X" ready, reason = self.instance.ready_to_run() self.assertTrue(ready) - self.instance.set_value("version", None) - self.instance.set_value("full_version", "Y") + self.instance.version = None + self.instance.full_version = "Y" ready, reason = self.instance.ready_to_run() self.assertTrue(ready) - self.instance.set_value("full_version", None) + self.instance.full_version = None ready, reason = self.instance.ready_to_run() self.assertFalse(ready) self.assertTrue(re.search("nothing to do", reason)) @@ -60,8 +60,8 @@ def test_readiness(self): def test_edit_short_version(self): """Editing the short version alone.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("version", "5.3.1") + self.instance.package = self.input_ovf + self.instance.version = "5.3.1" self.instance.run() self.instance.finished() self.check_diff(""" @@ -73,9 +73,8 @@ def test_edit_short_version(self): def test_edit_full_version(self): """Editing the full version alone.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("full_version", - "Some arbitrary product, version 3.14159") + self.instance.package = self.input_ovf + self.instance.full_version = "Some arbitrary product, version 3.14159" self.instance.run() self.instance.finished() self.check_diff(""" @@ -89,8 +88,8 @@ def test_edit_full_version(self): def test_edit_full_no_existing(self): """Edit full version in an OVF with no previous values.""" - self.instance.set_value("PACKAGE", self.minimal_ovf) - self.instance.set_value("full_version", "Full Version") + self.instance.package = self.minimal_ovf + self.instance.full_version = "Full Version" self.instance.run() self.instance.finished() self.check_diff(file1=self.minimal_ovf, @@ -105,9 +104,9 @@ def test_edit_full_no_existing(self): def test_edit_both_versions(self): """Edit both version strings""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("version", "5.2.0.01I") - self.instance.set_value("full_version", "Cisco IOS XRv, Version 5.2") + self.instance.package = self.input_ovf + self.instance.version = "5.2.0.01I" + self.instance.full_version = "Cisco IOS XRv, Version 5.2" self.instance.run() self.instance.finished() self.check_diff(""" @@ -122,9 +121,9 @@ def test_edit_both_versions(self): def test_edit_both_no_existing(self): """Edit both version strings in an OVF with no previous values.""" - self.instance.set_value("PACKAGE", self.minimal_ovf) - self.instance.set_value("version", "Version") - self.instance.set_value("full_version", "Full Version") + self.instance.package = self.minimal_ovf + self.instance.version = "Version" + self.instance.full_version = "Full Version" self.instance.run() self.instance.finished() self.check_diff(file1=self.minimal_ovf, diff --git a/COT/tests/edit_properties.py b/COT/tests/edit_properties.py index 643d807..9aaad75 100644 --- a/COT/tests/edit_properties.py +++ b/COT/tests/edit_properties.py @@ -28,12 +28,12 @@ def setUp(self): """Test case setup function called automatically prior to each test""" super(TestCOTEditProperties, self).setUp() self.instance = COTEditProperties(UI()) - self.instance.set_value("output", self.temp_file) + self.instance.output = self.temp_file def test_set_property_value(self): """Set the value of an existing property.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("properties", ["login-username=admin"]) + self.instance.package = self.input_ovf + self.instance.properties = ["login-username=admin"] self.instance.run() self.instance.finished() self.check_diff(""" @@ -47,10 +47,11 @@ def test_set_property_value(self): def test_set_multiple_property_values(self): """Set the value of several existing properties.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("properties", ["login-username=admin", - "login-password=cisco123", - "enable-ssh-server=1"]) + self.instance.package = self.input_ovf + self.instance.properties = [ + "login-username=admin", + "login-password=cisco123", + "enable-ssh-server=1"] self.instance.run() self.instance.finished() self.check_diff(""" @@ -80,8 +81,8 @@ def test_set_multiple_property_values(self): def test_create_property(self): """Create a new property but do not set its value yet.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("properties", ["new-property-2="]) + self.instance.package = self.input_ovf + self.instance.properties = ["new-property-2="] self.instance.run() self.instance.finished() self.check_diff(""" @@ -92,8 +93,8 @@ def test_create_property(self): def test_create_and_set_property(self): """Create a new property and set its value""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("properties", ["new-property=hello"]) + self.instance.package = self.input_ovf + self.instance.properties = ["new-property=hello"] self.instance.run() self.instance.finished() self.check_diff(""" @@ -105,10 +106,9 @@ def test_create_and_set_property(self): def test_load_config_file(self): """Inject a sequence of properties from a config file.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("config_file", - os.path.join(os.path.dirname(__file__), - "sample_cfg.txt")) + self.instance.package = self.input_ovf + self.instance.config_file = os.path.join(os.path.dirname(__file__), + "sample_cfg.txt") self.instance.run() self.instance.finished() self.check_diff(""" @@ -125,13 +125,11 @@ def test_load_config_file(self): def test_combined(self): """Set individual properties AND add from a config file.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("config_file", - os.path.join(os.path.dirname(__file__), - "sample_cfg.txt")) - self.instance.set_value("properties", - ["login-password=cisco123", - "enable-ssh-server=1"]) + self.instance.package = self.input_ovf + self.instance.config_file = os.path.join(os.path.dirname(__file__), + "sample_cfg.txt") + self.instance.properties = ["login-password=cisco123", + "enable-ssh-server=1"] self.instance.run() self.instance.finished() self.check_diff(""" @@ -165,7 +163,7 @@ def test_combined(self): def test_qualifiers(self): """Ensure property values are limited by qualifiers.""" - self.instance.set_value("PACKAGE", self.input_ovf) + self.instance.package = self.input_ovf vm = self.instance.vm self.assertRaises(ValueUnsupportedError, @@ -179,8 +177,8 @@ def test_qualifiers(self): def test_create_property_no_prexisting(self): """Set property values for an OVF that has none previously""" - self.instance.set_value("PACKAGE", self.minimal_ovf) - self.instance.set_value("properties", ["hello=world"]) + self.instance.package = self.minimal_ovf + self.instance.properties = ["hello=world"] self.instance.run() self.instance.finished() self.check_diff(file1=self.minimal_ovf, expected=""" @@ -194,9 +192,8 @@ def test_create_property_no_prexisting(self): def test_config_file_not_supported(self): """Platform doesn't support literal CLI configuration.""" - self.instance.set_value("PACKAGE", self.iosv_ovf) - self.instance.set_value("config_file", - os.path.join(os.path.dirname(__file__), - "sample_cfg.txt")) + self.instance.package = self.iosv_ovf + self.instance.config_file = os.path.join(os.path.dirname(__file__), + "sample_cfg.txt") self.assertRaises(NotImplementedError, self.instance.run) diff --git a/COT/tests/info.py b/COT/tests/info.py index 6742380..26e24c1 100644 --- a/COT/tests/info.py +++ b/COT/tests/info.py @@ -53,24 +53,17 @@ def test_readiness(self): self.assertEqual("At least one package must be specified", reason) self.assertRaises(InvalidInputError, self.instance.run) - self.instance.set_value("PACKAGE_LIST", [self.input_ovf]) + self.instance.package_list = [self.input_ovf] ready, reason = self.instance.ready_to_run() self.assertTrue(ready) def test_invalid_args(self): - self.assertRaises(InvalidInputError, - self.instance.set_value, - "PACKAGE_LIST", ["/foo/bar/baz"]) - self.assertRaises(InvalidInputError, - self.instance.set_value, - "verbosity", True) - self.assertRaises(InvalidInputError, - self.instance.set_value, - "verbosity", 0) - # info takes a PACKAGE_LIST not a PACKAGE at present - self.assertRaises(InvalidInputError, - self.instance.set_value, - "PACKAGE", self.input_ovf) + with self.assertRaises(InvalidInputError): + self.instance.package_list = ["/foo/bar/baz"] + with self.assertRaises(InvalidInputError): + self.instance.verbosity = True + with self.assertRaises(InvalidInputError): + self.instance.verbosity = 0 def test_minimal_ovf(self): """Get info for minimal OVF with no real content.""" @@ -83,20 +76,19 @@ def test_minimal_ovf(self): ---- --------- ---- ------- -------------- None (default) 0 0 MB 0 0 0 / 0 B """.format(self.minimal_ovf) - self.instance.set_value("PACKAGE_LIST", [self.minimal_ovf]) + self.instance.package_list = [self.minimal_ovf] self.check_cot_output(expected_output) - self.instance.set_value('verbosity', 'brief') + self.instance.verbosity = 'brief' self.check_cot_output(expected_output) - self.instance.set_value('verbosity', 'verbose') + self.instance.verbosity = 'verbose' self.check_cot_output(expected_output) def test_multiple_minimal_ovf(self): """Test multiple OVFs at once""" - self.instance.set_value("PACKAGE_LIST", - [self.minimal_ovf, self.minimal_ovf]) + self.instance.package_list = [self.minimal_ovf, self.minimal_ovf] self.check_cot_output(""" ------------------------------------------------------------------------------- {0} @@ -115,7 +107,7 @@ def test_multiple_minimal_ovf(self): def test_input_ovf(self): """Test the standard input ovf""" - self.instance.set_value('PACKAGE_LIST', [self.input_ovf]) + self.instance.package_list = [self.input_ovf] self.check_cot_output(""" ------------------------------------------------------------------------------- {0} @@ -170,7 +162,7 @@ def test_input_ovf(self): domain-name Domain Name "" """.format(self.input_ovf)) - self.instance.set_value('verbosity', 'brief') + self.instance.verbosity = 'brief' self.check_cot_output(""" ------------------------------------------------------------------------------- {0} @@ -211,7 +203,7 @@ def test_input_ovf(self): domain-name Domain Name "" """.format(self.input_ovf)) - self.instance.set_value('verbosity', 'verbose') + self.instance.verbosity = 'verbose' self.check_cot_output(""" ------------------------------------------------------------------------------- {0} @@ -288,9 +280,9 @@ def test_input_ovf(self): def test_iosv_ovf(self): """Test an IOSv OVF.""" - self.instance.set_value('PACKAGE_LIST', [self.iosv_ovf]) + self.instance.package_list = [self.iosv_ovf] - self.instance.set_value('verbosity', 'brief') + self.instance.verbosity = 'brief' self.check_cot_output(""" ------------------------------------------------------------------------------- {0} @@ -336,7 +328,7 @@ def test_iosv_ovf(self): GigabitEthernet0_15 "Data network 16" """.format(self.iosv_ovf)) - self.instance.set_value('verbosity', 'verbose') + self.instance.verbosity = 'verbose' self.check_cot_output(""" ------------------------------------------------------------------------------- {0} @@ -433,7 +425,7 @@ def test_iosv_ovf(self): def test_v09_ovf(self): """Test a legacy v0.9 OVF.""" - self.instance.set_value('PACKAGE_LIST', [self.v09_ovf]) + self.instance.package_list = [self.v09_ovf] self.check_cot_output(""" ------------------------------------------------------------------------------- {0} @@ -466,7 +458,7 @@ def test_v09_ovf(self): ethernet0 : bridged """.format(self.v09_ovf)) - self.instance.set_value('verbosity', 'verbose') + self.instance.verbosity = 'verbose' self.check_cot_output(""" ------------------------------------------------------------------------------- {0} @@ -507,7 +499,7 @@ def test_v09_ovf(self): def test_vmware_ovf(self): """Test info string for an OVF with VMware custom extensions.""" - self.instance.set_value('PACKAGE_LIST', [self.vmware_ovf]) + self.instance.package_list = [self.vmware_ovf] self.check_cot_output(""" ------------------------------------------------------------------------------- {0} @@ -535,7 +527,7 @@ def test_vmware_ovf(self): Network adapter 4 : lanethernet0 """.format(self.vmware_ovf)) - self.instance.set_value('verbosity', 'verbose') + self.instance.verbosity = 'verbose' self.check_cot_output(""" ------------------------------------------------------------------------------- {0} @@ -569,8 +561,8 @@ def test_vmware_ovf(self): def test_v20_vbox_ovf(self): """Test info string for v2.0 OVF generated by VirtualBox""" - self.instance.set_value("PACKAGE_LIST", [self.v20_vbox_ovf]) - self.instance.set_value("verbosity", "verbose") + self.instance.package_list = [self.v20_vbox_ovf] + self.instance.verbosity = "verbose" self.check_cot_output(""" ------------------------------------------------------------------------------- {0} @@ -598,8 +590,8 @@ def test_v20_vbox_ovf(self): def test_invalid_ovf(self): """Test info string for OVF with various invalid/atypical contents""" - self.instance.set_value("PACKAGE_LIST", [self.invalid_ovf]) - self.instance.set_value("verbosity", "verbose") + self.instance.package_list = [self.invalid_ovf] + self.instance.verbosity = "verbose" self.check_cot_output(""" ------------------------------------------------------------------------------- {0} @@ -654,7 +646,7 @@ def narrow_width(): self.instance.UI.terminal_width = narrow_width - self.instance.set_value("PACKAGE_LIST", [self.invalid_ovf]) + self.instance.package_list = [self.invalid_ovf] self.check_cot_output(""" ----------------------------------------------------------- {0} @@ -694,7 +686,7 @@ def narrow_width(): self.assertLogged(**self.UNRECOGNIZED_PRODUCT_CLASS) self.assertLogged(**self.NONEXISTENT_FILE) - self.instance.set_value("verbosity", "verbose") + self.instance.verbosity = "verbose" self.check_cot_output(""" ----------------------------------------------------------- {0} diff --git a/COT/tests/inject_config.py b/COT/tests/inject_config.py index f656fac..6291a5e 100644 --- a/COT/tests/inject_config.py +++ b/COT/tests/inject_config.py @@ -37,56 +37,53 @@ def setUp(self): """Test case setup function called automatically prior to each test""" super(TestCOTInjectConfig, self).setUp() self.instance = COTInjectConfig(UI()) - self.instance.set_value("output", self.temp_file) + self.instance.output = self.temp_file self.config_file = os.path.join(os.path.dirname(__file__), "sample_cfg.txt") def test_readiness(self): """Test ready_to_run() under various combinations of parameters.""" - self.instance.set_value("PACKAGE", self.input_ovf) + self.instance.package = self.input_ovf ready, reason = self.instance.ready_to_run() self.assertFalse(ready) self.assertTrue(re.search("No configuration files", reason)) self.assertRaises(InvalidInputError, self.instance.run) - self.instance.set_value("config_file", self.config_file) + self.instance.config_file = self.config_file ready, reason = self.instance.ready_to_run() self.assertTrue(ready) def test_invalid_always_args(self): """Test input values that are always invalid""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.assertRaises(InvalidInputError, - self.instance.set_value, "config_file", 0) - self.assertRaises(InvalidInputError, - self.instance.set_value, "secondary_config_file", 0) + self.instance.package = self.input_ovf + with self.assertRaises(InvalidInputError): + self.instance.config_file = 0 + with self.assertRaises(InvalidInputError): + self.instance.secondary_config_file = 0 def test_valid_by_platform(self): """Test input values whose validity depends on the platform.""" - self.instance.set_value("PACKAGE", self.input_ovf) + self.instance.package = self.input_ovf # IOSXRvLC supports neither primary nor secondary config files self.instance.vm.platform = IOSXRvLC - self.assertRaises(InvalidInputError, - self.instance.set_value, "config_file", - self.config_file) - self.assertRaises(InvalidInputError, - self.instance.set_value, "secondary_config_file", - self.config_file) + with self.assertRaises(InvalidInputError): + self.instance.config_file = self.config_file + with self.assertRaises(InvalidInputError): + self.instance.secondary_config_file = self.config_file # IOSv supports primary but not secondary self.instance.vm.platform = IOSv - self.instance.set_value("config_file", self.config_file) - self.assertRaises(InvalidInputError, - self.instance.set_value, "secondary_config_file", - self.config_file) + self.instance.config_file = self.config_file + with self.assertRaises(InvalidInputError): + self.instance.secondary_config_file = self.config_file # IOSXRv supports both self.instance.vm.platform = IOSXRv - self.instance.set_value("config_file", self.config_file) - self.instance.set_value("secondary_config_file", self.config_file) + self.instance.config_file = self.config_file + self.instance.secondary_config_file = self.config_file def test_inject_config_iso(self): """Inject config file on an ISO.""" - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("config_file", self.config_file) + self.instance.package = self.input_ovf + self.instance.config_file = self.config_file self.instance.run() self.assertLogged(**self.OVERWRITING_DISK_ITEM) self.instance.finished() @@ -107,9 +104,9 @@ def test_inject_config_iso(self): def test_inject_config_iso_secondary(self): """Inject secondary config file on an ISO.""" - self.instance.set_value("PACKAGE", self.input_ovf) + self.instance.package = self.input_ovf self.instance.vm.platform = IOSXRv - self.instance.set_value("secondary_config_file", self.config_file) + self.instance.secondary_config_file = self.config_file self.instance.run() self.assertLogged(**self.OVERWRITING_DISK_ITEM) self.instance.finished() @@ -130,8 +127,8 @@ def test_inject_config_iso_secondary(self): def test_inject_config_vmdk(self): """Inject config file on a VMDK""" - self.instance.set_value("PACKAGE", self.iosv_ovf) - self.instance.set_value("config_file", self.config_file) + self.instance.package = self.iosv_ovf + self.instance.config_file = self.config_file self.instance.run() self.assertLogged(**self.OVERWRITING_DISK) self.assertLogged(**self.OVERWRITING_DISK_ITEM) @@ -172,22 +169,22 @@ def test_inject_config_vmdk(self): def test_inject_config_repeatedly(self): """inject-config repeatedly""" # Add initial config file - self.instance.set_value("PACKAGE", self.input_ovf) - self.instance.set_value("config_file", self.config_file) + self.instance.package = self.input_ovf + self.instance.config_file = self.config_file self.instance.run() self.assertLogged(**self.OVERWRITING_DISK_ITEM) self.instance.finished() # Overwrite it with a new one - self.instance.set_value("PACKAGE", self.temp_file) - self.instance.set_value("config_file", self.config_file) + self.instance.package = self.temp_file + self.instance.config_file = self.config_file self.instance.run() self.assertLogged(**self.OVERWRITE_CONFIG_DISK) self.assertLogged(**self.OVERWRITING_FILE) self.assertLogged(**self.OVERWRITING_DISK_ITEM) self.instance.finished() # And again. - self.instance.set_value("PACKAGE", self.temp_file) - self.instance.set_value("config_file", self.config_file) + self.instance.package = self.temp_file + self.instance.config_file = self.config_file self.instance.run() self.assertLogged(**self.OVERWRITE_CONFIG_DISK) self.assertLogged(**self.OVERWRITING_FILE) @@ -210,8 +207,8 @@ def test_inject_config_repeatedly(self): def test_inject_config_fail_no_disk_available(self): """Error handling if the OVF doesn't have an appropriate drive.""" - self.instance.set_value("PACKAGE", self.minimal_ovf) - self.instance.set_value("config_file", self.config_file) + self.instance.package = self.minimal_ovf + self.instance.config_file = self.config_file # CSR1000V wants a CD-ROM drive self.instance.vm.platform = CSR1000V self.assertRaises(LookupError, self.instance.run) @@ -220,13 +217,13 @@ def test_inject_config_fail_no_disk_available(self): self.assertRaises(LookupError, self.instance.run) # Also fail due to DiskSection but no placeholder: - self.instance.set_value("PACKAGE", self.input_ovf) + self.instance.package = self.input_ovf self.instance.vm.platform = IOSv self.assertRaises(LookupError, self.instance.run) def test_find_parent_fail_no_parent(self): """Negative testing of some inject-config related APIs.""" - self.instance.set_value("PACKAGE", self.input_ovf) + self.instance.package = self.input_ovf cpu_item = self.instance.vm.hardware.find_item( resource_type='cpu') self.assertRaises(LookupError, diff --git a/COT/tests/submodule.py b/COT/tests/submodule.py index bd741d7..e74d3a1 100644 --- a/COT/tests/submodule.py +++ b/COT/tests/submodule.py @@ -17,7 +17,6 @@ from COT.tests.ut import COT_UT from COT.ui_shared import UI from COT.submodule import COTSubmodule -from COT.data_validation import InvalidInputError from COT.vm_description import VMInitError @@ -27,21 +26,13 @@ class TestCOTSubmodule(COT_UT): def setUp(self): """Test case setup function called automatically prior to each test""" super(TestCOTSubmodule, self).setUp() - self.instance = COTSubmodule(UI(), []) - self.instance.set_value("output", self.temp_file) + self.instance = COTSubmodule(UI()) + self.instance.output = self.temp_file def test_vmfactory_fail(self): - self.instance.set_value("output", "foo.vmx") - self.assertRaises(VMInitError, - self.instance.set_value, "PACKAGE", self.input_ovf) - - def test_validate_fail(self): - valid, reason = self.instance.validate_arg("hello", "world") - self.assertFalse(valid) - - def test_set_value_fail(self): - self.assertRaises(InvalidInputError, - self.instance.set_value, "hello", "world") + self.instance.output = "foo.vmx" + with self.assertRaises(VMInitError): + self.instance.package = self.input_ovf def test_create_subparser_noop(self): label, subparser = self.instance.create_subparser(None)