def test_automate_ansible_playbook_method_type(request, appliance, ansible_repository, domain, namespace, klass): """Tests execution an ansible playbook via ansible playbook method using Simulation. Polarion: assignee: ghubale casecomponent: Automate initialEstimate: 1/4h """ klass.schema.add_field(name="execute", type="Method", data_type="String") method = klass.methods.create( name=fauxfactory.gen_alphanumeric(), location="playbook", repository=ansible_repository.name, playbook="copy_file_example.yml", machine_credential="CFME Default Credential", playbook_input_parameters=[("key", "value", "string")] ) instance = klass.instances.create( name=fauxfactory.gen_alphanumeric(), description=fauxfactory.gen_alphanumeric(), fields={"execute": {"value": method.name}}) simulate( appliance=appliance, request="Call_Instance", attributes_values={ "namespace": "{}/{}".format(domain.name, namespace.name), "class": klass.name, "instance": instance.name } ) request.addfinalizer(lambda: appliance.ssh_client.run_command( '[[ -f "/var/tmp/modified-release" ]] && rm -f "/var/tmp/modified-release"')) assert appliance.ssh_client.run_command('[ -f "/var/tmp/modified-release" ]').success
def test_automate_instance_missing(domain, klass, namespace, appliance): """If an instance called in class does not exist, a .missing instance is processed if it exists. A _missing_instance attribute (which contains the name of the instance that was supposed to be called) is then set on $evm.object so it then can be used eg. to resolve methods dynamically. """ catch_string = fauxfactory.gen_alphanumeric() method = klass.methods.create( name=fauxfactory.gen_alphanumeric(), location='inline', script='$evm.log(:info, "{}")'.format(catch_string), ) klass.schema.add_fields({'name': 'mfield', 'type': 'Method', 'data_type': 'String'}) klass.instances.create(name='.missing', fields={'mfield': {'value': '${#_missing_instance}'}}) klass2 = namespace.classes.create(name=fauxfactory.gen_alpha()) klass2.schema.add_fields({'name': 'rel', 'type': 'Relationship'}) instance2 = klass2.instances.create( name=fauxfactory.gen_alphanumeric(), fields={'rel': {'value': '/' + '/'.join(method.tree_path_name_only[1:])}} ) simulate( appliance=appliance, request='Call_Instance', attributes_values={ 'namespace': '{}/{}'.format(domain.name, namespace.name), 'class': klass2.name, 'instance': instance2.name } ) assert appliance.ssh_client.run_command( 'grep {} /var/www/miq/vmdb/log/automation.log'.format(catch_string)).success
def test_assert_failed_substitution(copy_class): """ Polarion: assignee: ghubale casecomponent: Automate caseimportance: medium initialEstimate: 1/4h caseposneg: negative tags: automate Bugzilla: 1335669 """ # Adding instance and invalid value for assertion field - 'guard' instance = copy_class.instances.create( name=fauxfactory.gen_alphanumeric(), display_name=fauxfactory.gen_alphanumeric(), description=fauxfactory.gen_alphanumeric(), fields={'guard': {'value': "${/#this_value_does_not_exist}"}} ) # Executing automate instance using simulation with pytest.raises(AssertionError, match="Automation Error: Attribute this_value_does_not_exist not found"): simulate( appliance=copy_class.appliance, attributes_values={ "namespace": copy_class.namespace.name, "class": copy_class.name, "instance": instance.name, }, message="create", request="Call_Instance", execute_methods=True, )
def test_check_system_request_calls_depr_conf_mgmt(appliance, copy_instance): """ Polarion: assignee: ghubale initialEstimate: 1/8h caseimportance: low caseposneg: positive testtype: functional startsin: 5.10 casecomponent: Automate tags: automate setup: 1. Copy /System/Request/ansible_tower_job instance to new domain testSteps: 1. Run that instance(ansible_tower_job) using simulation 2. See automation log expectedResults: 1. 2. The /System/Request/ansible_tower_job instance should call the newer "/AutomationManagement/AnsibleTower/Operations/StateMachines/Job/default" method Bugzilla: 1615444 """ search = '/AutomationManagement/AnsibleTower/Operations/StateMachines/Job/default' result = LogValidator( "/var/www/miq/vmdb/log/automation.log", matched_patterns=[".*{}.*".format(search)] ) result.start_monitoring() # Executing the automate instance - 'ansible_tower_job' using simulation simulate( appliance=appliance, request=copy_instance.name ) assert result.validate(wait="60s")
def test_delete_tag_from_category(custom_instance): """ Bugzilla: 1744514 1767901 Polarion: assignee: dgaikwad casecomponent: Automate initialEstimate: 1/12h """ instance = custom_instance(ruby_code=tag_delete_from_category) with LogValidator( "/var/www/miq/vmdb/log/automation.log", matched_patterns=[ f'.*Tag exists: {value}.*' for value in ['true', 'false'] ], ).waiting(timeout=120): # Executing automate method using simulation simulate( appliance=instance.klass.appliance, message="create", request="Call_Instance", execute_methods=True, attributes_values={ "namespace": instance.klass.namespace.name, "class": instance.klass.name, "instance": instance.name, }, )
def test_list_of_diff_vm_storages_via_rails(appliance, setup_provider, provider, testing_vm, custom_instance): """ Bugzilla: 1574444 Polarion: assignee: dgaikwad initialEstimate: 1/8h caseimportance: medium caseposneg: positive testtype: functional startsin: 5.9 casecomponent: Automate testSteps: 1. vmware = $evm.vmdb('ems').find_by_name('vmware 6.5 (nested)') ; 2. vm = vmware.vms.select { |v| v.name == 'dgaikwad-cfme510' }.first ; 3. vm.storage 4. vm.storages expectedResults: 1. 2. 3. Returns only one storage 4. Returns available storages """ list_storages = dedent( f'vmware = $evm.vmdb("ems").find_by_name("{provider.name}")\n' 'vm = vmware.vms.select {|v| v.name == ' f'"{testing_vm.name}"' '}.first\n' 'storage = vm.storage\n' 'storage_name = storage.name\n' '$evm.log(:info, "storage name: #{storage_name}")\n' 'storages = vm.storages\n' 'storage_name = storages[0].name\n' '$evm.log(:info, "storages name: #{storage_name}")\n') instance = custom_instance(ruby_code=list_storages) with LogValidator( "/var/www/miq/vmdb/log/automation.log", matched_patterns=[ f".*storage name: {testing_vm.datastore.name}.*", f".*storages name: {testing_vm.datastore.name}.*", ], ).waiting(timeout=120): # Executing automate method using simulation simulate( appliance=appliance, message="create", request="Call_Instance", execute_methods=True, attributes_values={ "namespace": instance.klass.namespace.name, "class": instance.klass.name, "instance": instance.name, }, )
def test_domain_lock_disabled(klass): """ Polarion: assignee: ghubale casecomponent: Automate caseimportance: medium initialEstimate: 1/16h tags: automate """ schema_field = fauxfactory.gen_alphanumeric() # Disable automate domain with update(klass.namespace.domain): klass.namespace.domain.enabled = False # Adding schema for executing automate method klass.schema.add_fields({'name': schema_field, 'type': 'Method', 'data_type': 'String'}) # Adding automate method method = klass.methods.create( name=fauxfactory.gen_alphanumeric(), display_name=fauxfactory.gen_alphanumeric(), location='inline' ) # Adding instance to call automate method instance = klass.instances.create( name=fauxfactory.gen_alphanumeric(), display_name=fauxfactory.gen_alphanumeric(), description=fauxfactory.gen_alphanumeric(), fields={schema_field: {'value': method.name}} ) result = LogValidator( "/var/www/miq/vmdb/log/automation.log", matched_patterns=[r".*ERROR.*"], ) result.start_monitoring() # Executing automate method using simulation simulate( appliance=klass.appliance, attributes_values={ "namespace": klass.namespace.name, "class": klass.name, "instance": instance.name, }, message="create", request="Call_Instance", execute_methods=True, ) assert result.validate(wait="60s") klass.namespace.domain.lock() view = navigate_to(klass.namespace.domain, 'Details') assert 'Disabled' in view.title.text assert 'Locked' in view.title.text # Need to unlock the domain to perform teardown on domain, namespace, class klass.namespace.domain.unlock()
def test_miq_password_decrypt(klass): """ Polarion: assignee: ghubale casecomponent: Automate initialEstimate: 1/3h Bugzilla: 1720432 """ # Ruby script for decrypting password script = ( 'require "manageiq-password"\n' 'root_password = MiqPassword.encrypt("abc")\n' '$evm.log("info", "Root Password is #{root_password}")\n' 'root_password_decrypted = MiqPassword.decrypt(root_password)\n' '$evm.log("info", "Decrypted password is #{root_password_decrypted}")') # Adding schema for executing method klass.schema.add_fields({ 'name': 'execute', 'type': 'Method', 'data_type': 'String' }) # Adding automate method method = klass.methods.create(name=fauxfactory.gen_alphanumeric(), display_name=fauxfactory.gen_alphanumeric(), location='inline', script=script) # Adding instance to call automate method instance = klass.instances.create( name=fauxfactory.gen_alphanumeric(), display_name=fauxfactory.gen_alphanumeric(), description=fauxfactory.gen_alphanumeric(), fields={'execute': { 'value': method.name }}) result = LogValidator( "/var/www/miq/vmdb/log/automation.log", matched_patterns=[".*Decrypted password is abc.*"], ) result.start_monitoring() # Executing method via simulation to check decrypted password simulate( appliance=klass.appliance, attributes_values={ "namespace": klass.namespace.name, "class": klass.name, "instance": instance.name, }, message="create", request="Call_Instance", execute_methods=True, ) assert result.validate()
def test_create_snapshot_via_ae(appliance, request, domain, small_test_vm): """This test checks whether the vm.create_snapshot works in AE. Prerequisities: * A VMware provider * A VM that has been discovered by CFME Steps: * Clone the Request class inside the System namespace into a new domain * Add a method named ``snapshot`` and insert the provided code there. * Add an instance named ``snapshot`` and set the methd from previous step as ``meth5`` * Run the simulation of the method against the VM, preferably setting ``snap_name`` to something that can be checked * Wait until snapshot with such name appears. Polarion: assignee: apagac casecomponent: Infra caseimportance: medium initialEstimate: 1/3h """ # PREPARE file = data_path.join("ui").join("automate").join("test_create_snapshot_via_ae.rb") with file.open("r") as f: method_contents = f.read() miq_domain = DomainCollection(appliance).instantiate(name='ManageIQ') miq_class = miq_domain.namespaces.instantiate(name='System').classes.instantiate(name='Request') miq_class.copy_to(domain) request_cls = domain.namespaces.instantiate(name='System').classes.instantiate(name='Request') request.addfinalizer(request_cls.delete) method = request_cls.methods.create(name="snapshot", location='inline', script=method_contents) request.addfinalizer(method.delete) instance = request_cls.instances.create( name="snapshot", fields={ "meth5": { 'value': "snapshot"}}) request.addfinalizer(instance.delete) # SIMULATE snap_name = fauxfactory.gen_alpha() snapshot = InfraVm.Snapshot(name=snap_name, parent_vm=small_test_vm) simulate( appliance=appliance, instance="Request", request="snapshot", target_type='VM and Instance', target_object=small_test_vm.name, execute_methods=True, attributes_values={"snap_name": snap_name}) wait_for(lambda: snapshot.exists, timeout="2m", delay=10, fail_func=small_test_vm.provider.browser.refresh, handle_exception=True, message="Waiting for snapshot create") # Clean up if it appeared snapshot.delete()
def test_create_snapshot_via_ae(appliance, request, domain, small_test_vm): """This test checks whether the vm.create_snapshot works in AE. Prerequisities: * A VMware provider * A VM that has been discovered by CFME Steps: * Clone the Request class inside the System namespace into a new domain * Add a method named ``snapshot`` and insert the provided code there. * Add an instance named ``snapshot`` and set the methd from previous step as ``meth5`` * Run the simulation of the method against the VM, preferably setting ``snap_name`` to something that can be checked * Wait until snapshot with such name appears. """ # PREPARE file = data_path.join("ui").join("automate").join( "test_create_snapshot_via_ae.rb") with file.open("r") as f: method_contents = f.read() miq_domain = DomainCollection(appliance).instantiate(name='ManageIQ') miq_class = miq_domain.namespaces.instantiate( name='System').classes.instantiate(name='Request') miq_class.copy_to(domain) request_cls = domain.namespaces.instantiate( name='System').classes.instantiate(name='Request') request.addfinalizer(request_cls.delete) method = request_cls.methods.create(name="snapshot", location='inline', script=method_contents) request.addfinalizer(method.delete) instance = request_cls.instances.create( name="snapshot", fields={"meth5": { 'value': "snapshot" }}) request.addfinalizer(instance.delete) # SIMULATE snap_name = fauxfactory.gen_alpha() snapshot = InfraVm.Snapshot(name=snap_name, parent_vm=small_test_vm) simulate(appliance=appliance, instance="Request", request="snapshot", target_type='VM and Instance', target_object=small_test_vm.name, execute_methods=True, attributes_values={"snap_name": snap_name}) wait_for(lambda: snapshot.exists, timeout="2m", delay=10, fail_func=small_test_vm.provider.browser.refresh, handle_exception=True, message="Waiting for snapshot create") # Clean up if it appeared snapshot.delete()
def test_simulated_object_copy_on_button(appliance, provider, setup_provider, button_type): """ Test copy of simulated object over custom button Polarion: assignee: ndhandre initialEstimate: 1/4h caseimportance: medium caseposneg: positive casecomponent: CustomButton tags: custom_button testSteps: 1. simulate button with Automate -> Simulation 2. copy simulated data 3. paste simulated data on button from Automate -> Customizationn -> Buttons 4. check copy-paste working or not Bugzilla: 1426390 1719282 """ if button_type == "User": target_type = "{}User".format( "EVM " if appliance.version < "5.11" else "") target_obj = "Administrator" else: target_type = "Provider" target_obj = provider.name # simulate and copy simulate( appliance=appliance, instance="Automation", message="test_bz", request="InspectMe", target_type=target_type, target_object=target_obj, execute_methods=True, pre_clear=True, ) view = appliance.browser.create_view(AutomateSimulationView, wait="15s") view.copy.click() # paste data while creating button button_coll = appliance.collections.buttons button_coll.group = appliance.collections.button_groups.instantiate( text="[Unassigned Buttons]", hover="Unassigned buttons", type=button_type) view = navigate_to(button_coll, "Add") view.paste.click() assert view.advanced.system.read() == "Automation" assert view.advanced.message.read() == "test_bz" assert view.advanced.request.read() == "InspectMe"
def test_move_vm_into_folder(appliance, vm_folder, testing_vm, custom_instance): """ Bugzilla: 1716858 Polarion: assignee: ghubale casecomponent: Automate initialEstimate: 1/4h tags: automate """ script = dedent(f""" vm = $evm.vmdb('vm').find_by_name('{testing_vm.name}') folder = $evm.vmdb('EmsFolder').find_by(:name => '{vm_folder.name}') vm.move_into_folder(folder) unless folder.nil? """) instance = custom_instance(ruby_code=script) view = navigate_to(testing_vm, "Details") tree_path = view.sidebar.vmstemplates.tree.currently_selected simulate( appliance=appliance, attributes_values={ "namespace": instance.klass.namespace.name, "class": instance.klass.name, "instance": instance.name, }, message="create", request="Call_Instance", execute_methods=True, ) # manipulate tree path. Remove folder - 'Templates' and append with vm_folder name tree_path.pop() tree_path.append(vm_folder.name) # Navigating to Vms details page and checking folder of the Vm in accordion of CFME UI view = navigate_to(testing_vm, "Details") # Checking new folder appeared def _check(): try: view.sidebar.vmstemplates.tree.fill(tree_path) return True except CandidateNotFound: return False wait_for(lambda: _check, fail_func=view.browser.refresh, timeout=600, delay=5, message="Waiting for vm folder name to appear")
def test_automate_simulation_result_has_hash_data(custom_instance): """ The UI should display the result objects if the Simulation Result has hash data. Bugzilla: 1445089 Polarion: assignee: dgaikwad casecomponent: Automate caseimportance: medium initialEstimate: 1/6h tags: automate testSteps: 1. Create a Instance under /System/Request called ListUser, update it so that it points to a ListUser Method 2. Create ListUser Method under /System/Request, paste the Attached Method 3. Run Simulation expectedResults: 1. 2. 3. The UI should display the result objects """ instance = custom_instance(ruby_code=user_list_hash_data) # Executing automate method with LogValidator("/var/www/miq/vmdb/log/automation.log", matched_patterns=[ '.*User List.*:id=>1, :name=>"Fred".*' ]).waiting(timeout=120): simulate( appliance=instance.appliance, attributes_values={ "namespace": instance.klass.namespace.name, "class": instance.klass.name, "instance": instance.name, }, message="create", request="Call_Instance", execute_methods=True, ) view = instance.create_view(AutomateSimulationView) assert (view.result_tree.click_path( f"ManageIQ/SYSTEM / PROCESS / {instance.klass.name}", f"ManageIQ/System / {instance.klass.name} / Call_Instance", f"{instance.domain.name}/System / {instance.klass.name} / {instance.name}", "values", "Hash", "Key", ).text == "Key")
def test_automate_ansible_playbook_method_type(request, appliance, domain, namespace, klass, instance, method): """Tests execution an ansible playbook via ansible playbook method using Simulation.""" simulate( appliance=appliance, request="Call_Instance", attributes_values={ "namespace": "{}/{}".format(domain.name, namespace.name), "class": klass.name, "instance": instance.name } ) request.addfinalizer(lambda: appliance.ssh_client.run_command( "if [ -f \"/var/tmp/modified-release\" ]; then rm \"/var/tmp/modified-release\"")) assert appliance.ssh_client.run_command("[ -f \"/var/tmp/modified-release\" ]").success
def test_add_vm_to_service(service_vm, request, copy_domain, new_vm, appliance): """Tests adding vm to service Metadata: test_flag: provision Polarion: assignee: nansari casecomponent: Services initialEstimate: 1/4h tags: service """ myservice, _ = service_vm method_torso = """ def add_to_service vm = $evm.root['vm'] service = $evm.vmdb('service').find_by_name('{}') user = $evm.root['user'] if service && vm $evm.log('info', "XXXXXXXX Attaching Service to VM: [#{{service.name}}][#{{vm.name}}]") vm.add_to_service(service) vm.owner = user if user vm.group = user.miq_group if user end end $evm.log("info", "Listing Root Object Attributes:") $evm.log("info", "===========================================") add_to_service """.format(myservice.name) method = copy_domain\ .namespaces.instantiate(name='System')\ .classes.instantiate(name='Request')\ .methods.create(name='InspectMe', location='inline', script=method_torso) request.addfinalizer(method.delete_if_exists) simulate(appliance=appliance, instance="Request", message="create", request=method.name, target_type='VM and Instance', target_object=new_vm.name, execute_methods=True) myservice.check_vm_add(new_vm)
def test_add_vm_to_service(myservice, request, copy_domain): """Tests adding vm to service Metadata: test_flag: provision """ method_torso = """ def add_to_service vm = $evm.root['vm'] service = $evm.vmdb('service').find_by_name('{}') user = $evm.root['user'] if service && vm $evm.log('info', "XXXXXXXX Attaching Service to VM: [#{{service.name}}][#{{vm.name}}]") vm.add_to_service(service) vm.owner = user if user vm.group = user.miq_group if user end end $evm.log("info", "Listing Root Object Attributes:") $evm.log("info", "===========================================") add_to_service """.format(myservice.service_name) method = Method( name="InspectMe", data=method_torso, cls=Class( name="Request", namespace=Namespace( name="System", parent=copy_domain ) ) ) method.create() request.addfinalizer(lambda: method.delete() if method.exists() else None) simulate( instance="Request", message="create", request=method.name, attribute=["VM and Instance", "auto_test_services"], # Random selection, does not matter execute_methods=True ) myservice.check_vm_add("auto_test_services") request.addfinalizer(lambda: myservice.delete(myservice.service_name))
def test_add_vm_to_service(myservice, request, copy_domain): """Tests adding vm to service Metadata: test_flag: provision """ method_torso = """ def add_to_service vm = $evm.root['vm'] service = $evm.vmdb('service').find_by_name('%s') user = $evm.root['user'] if service && vm $evm.log('info', "XXXXXXXX Attaching Service to VM: [#{service.name}][#{vm.name}]") vm.add_to_service(service) vm.owner = user if user vm.group = user.miq_group if user end end $evm.log("info", "Listing Root Object Attributes:") $evm.log("info", "===========================================") add_to_service """ % myservice.service_name method = Method( name="InspectMe", data=method_torso, cls=Class( name="Request", namespace=Namespace( name="System", parent=copy_domain ) ) ) method.create() request.addfinalizer(lambda: method.delete() if method.exists() else None) simulate( instance="Request", message="create", request=method.name, attribute=["VM and Instance", "auto_test_services"], # Random selection, does not matter execute_methods=True ) myservice.check_vm_add("auto_test_services") request.addfinalizer(lambda: myservice.delete(myservice.service_name))
def test_create_snapshot_via_ae(request, domain, test_vm): """This test checks whether the vm.create_snapshot works in AE. Prerequisities: * A VMware provider * A VM that has been discovered by CFME Steps: * Clone the Request class inside the System namespace into a new domain * Add a method named ``snapshot`` and insert the provided code there. * Add an instance named ``snapshot`` and set the methd from previous step as ``meth5`` * Run the simulation of the method against the VM, preferably setting ``snap_name`` to something that can be checked * Wait until snapshot with such name appears. """ # PREPARE file = data_path.join("ui").join("automate").join( "test_create_snapshot_via_ae.rb") with file.open("r") as f: method_contents = f.read() miq_domain = Domain("ManageIQ (Locked)") miq_class = Class("Request", namespace=Namespace("System", domain=miq_domain)) request_cls = miq_class.copy_to(domain) request.addfinalizer(request_cls.delete) method = Method("snapshot", data=method_contents, cls=request_cls) method.create() request.addfinalizer(method.delete) instance = Instance("snapshot", values={"meth5": "snapshot"}, cls=request_cls) instance.create() request.addfinalizer(instance.delete) # SIMULATE snap_name = fauxfactory.gen_alpha() snapshot = Vm.Snapshot(name=snap_name, parent_vm=test_vm) simulate(instance="Request", request="snapshot", attribute=["VM and Instance", test_vm.name], execute_methods=True, avp={"snap_name": snap_name}) wait_for(snapshot.does_snapshot_exist, timeout="2m", delay=10) # Clean up if it appeared snapshot.delete()
def test_add_vm_to_service(request, myservice, create_method): """Tests adding vm to service Metadata: test_flag: provision """ simulate( instance="Request", message="create", request=create_method.name, attribute=["VM and Instance", "auto_test_services"], # Random selection, does not matter execute_methods=True ) myservice.check_vm_add("auto_test_services") request.addfinalizer(lambda: myservice.delete(item_name))
def test_create_snapshot_via_ae(request, domain, test_vm): """This test checks whether the vm.create_snapshot works in AE. Prerequisities: * A VMware provider * A VM that has been discovered by CFME Steps: * Clone the Request class inside the System namespace into a new domain * Add a method named ``snapshot`` and insert the provided code there. * Add an instance named ``snapshot`` and set the methd from previous step as ``meth5`` * Run the simulation of the method against the VM, preferably setting ``snap_name`` to something that can be checked * Wait until snapshot with such name appears. """ # PREPARE file = data_path.join("ui").join("automate").join("test_create_snapshot_via_ae.rb") with file.open("r") as f: method_contents = f.read() miq_domain = DomainCollection().instantiate(name='ManageIQ') miq_class = miq_domain.namespaces.instantiate(name='System').classes.instantiate(name='Request') miq_class.copy_to(domain) request_cls = domain.namespaces.instantiate(name='System').classes.instantiate(name='Request') request.addfinalizer(request_cls.delete) method = request_cls.methods.create(name="snapshot", location='inline', script=method_contents) request.addfinalizer(method.delete) instance = request_cls.instances.create( name="snapshot", fields={ "meth5": { 'value': "snapshot"}}) request.addfinalizer(instance.delete) # SIMULATE snap_name = fauxfactory.gen_alpha() snapshot = Vm.Snapshot(name=snap_name, parent_vm=test_vm) simulate( instance="Request", request="snapshot", attribute=["VM and Instance", test_vm.name], execute_methods=True, avp={"snap_name": snap_name}) wait_for(snapshot.does_snapshot_exist, timeout="2m", delay=10) # Clean up if it appeared snapshot.delete()
def test_automate_instance_missing(domain, klass, namespace, appliance): """If an instance called in class does not exist, a .missing instance is processed if it exists. A _missing_instance attribute (which contains the name of the instance that was supposed to be called) is then set on $evm.object so it then can be used eg. to resolve methods dynamically. Polarion: assignee: ghubale casecomponent: Automate caseimportance: high initialEstimate: 1/10h tags: automate """ catch_string = fauxfactory.gen_alphanumeric() method = klass.methods.create( name=fauxfactory.gen_alphanumeric(), location='inline', script='$evm.log(:info, "{}")'.format(catch_string), ) klass.schema.add_fields({ 'name': 'mfield', 'type': 'Method', 'data_type': 'String' }) klass.instances.create( name='.missing', fields={'mfield': { 'value': '${#_missing_instance}' }}) klass2 = namespace.classes.create(name=fauxfactory.gen_alpha()) klass2.schema.add_fields({'name': 'rel', 'type': 'Relationship'}) instance2 = klass2.instances.create( name=fauxfactory.gen_alphanumeric(), fields={ 'rel': { 'value': '/' + '/'.join(method.tree_path_name_only[1:]) } }) simulate(appliance=appliance, request='Call_Instance', attributes_values={ 'namespace': '{}/{}'.format(domain.name, namespace.name), 'class': klass2.name, 'instance': instance2.name }) assert appliance.ssh_client.run_command( 'grep {} /var/www/miq/vmdb/log/automation.log'.format( catch_string)).success
def test_override_method_across_domains( request, ssh_client, original_method, original_instance, copy_domain, original_method_write_data, copy_method_write_data, setup_a_provider): instance = original_instance ssh_client.run_command("rm -f {}".format(FILE_LOCATION)) request.addfinalizer(lambda: ssh_client.run_command("rm -f {}".format(FILE_LOCATION))) set_domain_order([Domain.default.name]) # Default first simulate( instance="Request", message="create", request=instance.name, attribute=None, # Random selection, does not matter execute_methods=True ) wait_for( lambda: ssh_client.run_command("cat {}".format(FILE_LOCATION))[0] == 0, num_sec=120, delay=0.5, message="wait for file to appear" ) rc, stdout = ssh_client.run_command("cat {}".format(FILE_LOCATION)) assert stdout.strip() == original_method_write_data ssh_client.run_command("rm -f {}".format(FILE_LOCATION)) copied_method = original_method.copy_to(copy_domain) request.addfinalizer(lambda: copied_method.delete()) # Set up a different thing to write to the file with update(copied_method): copied_method.data = METHOD_TORSO.format(copy_method_write_data) # Set it as the first one set_domain_order([copy_domain.name]) # And verify # # SECOND SIMULATION # simulate( instance="Request", message="create", request=instance.name, attribute=None, # Random selection, does not matter execute_methods=True ) wait_for( lambda: ssh_client.run_command("cat {}".format(FILE_LOCATION))[0] == 0, num_sec=120, delay=0.5, message="wait for file to appear" ) rc, stdout = ssh_client.run_command("cat {}".format(FILE_LOCATION)) assert stdout.strip() == copy_method_write_data
def test_add_vm_to_service(myservice, request, copy_domain, new_vm, appliance): """Tests adding vm to service Metadata: test_flag: provision Polarion: assignee: nansari initialEstimate: 1/4h """ method_torso = """ def add_to_service vm = $evm.root['vm'] service = $evm.vmdb('service').find_by_name('{}') user = $evm.root['user'] if service && vm $evm.log('info', "XXXXXXXX Attaching Service to VM: [#{{service.name}}][#{{vm.name}}]") vm.add_to_service(service) vm.owner = user if user vm.group = user.miq_group if user end end $evm.log("info", "Listing Root Object Attributes:") $evm.log("info", "===========================================") add_to_service """.format(myservice.name) method = copy_domain\ .namespaces.instantiate(name='System')\ .classes.instantiate(name='Request')\ .methods.create(name='InspectMe', location='inline', script=method_torso) request.addfinalizer(method.delete_if_exists) simulate( appliance=appliance, instance="Request", message="create", request=method.name, target_type='VM and Instance', target_object=new_vm.name, execute_methods=True ) myservice.check_vm_add(new_vm)
def test_automate_user_has_groups(request, appliance, custom_instance): """ This method should work: groups = $evm.vmdb(:user).first.miq_groups $evm.log(:info, "Displaying the user"s groups: #{groups.inspect}") Bugzilla: 1411424 Polarion: assignee: dgaikwad casecomponent: Automate caseimportance: medium initialEstimate: 1/12h tags: automate startsin: 5.8 """ user, user_data = _users(request, appliance) script = dedent( f""" group = $evm.vmdb(:user).find_by_name("{user[0].name}").miq_groups $evm.log(:info, "Displaying the user's groups: #{{group.inspect}}") """ ) instance = custom_instance(ruby_code=script) with LogValidator( "/var/www/miq/vmdb/log/automation.log", matched_patterns=[f'.*{user_data[0]["group"]["description"]}.*'], ).waiting(timeout=120): # Executing automate method using simulation simulate( appliance=instance.klass.appliance, message="create", request="Call_Instance", execute_methods=True, attributes_values={ "namespace": instance.klass.namespace.name, "class": instance.klass.name, "instance": instance.name, }, )
def test_attribute_value_message(custom_instance): """ Bugzilla: 1753523 1740761 Polarion: assignee: dgaikwad initialEstimate: 1/8h caseposneg: positive casecomponent: Automate setup: 1. Create domain, namespace, class and instance pointing to method testSteps: 1. Navigate to automate > automation > simulation page 2. Fill values for attribute/value pairs of namespace, class, instance and add message attribute with any value and click on submit. 3. See automation.log expectedResults: 1. 2. 3. Custom message attribute should be considered with instance in logs """ instance = custom_instance(ruby_code=None) msg = fauxfactory.gen_alphanumeric() # Executing automate method with LogValidator("/var/www/miq/vmdb/log/automation.log", matched_patterns=[f".*{instance.name}#{msg}.*" ]).waiting(timeout=120): simulate( appliance=instance.appliance, attributes_values={ "namespace": instance.klass.namespace.name, "class": instance.klass.name, "instance": instance.name, "message": msg }, message="create", request="call_instance_with_message", execute_methods=True, )
def test_add_vm_to_service(myservice, request, copy_domain): """Tests adding vm to service Metadata: test_flag: provision """ method_torso = """ def add_to_service vm = $evm.root['vm'] service = $evm.vmdb('service').find_by_name('{}') user = $evm.root['user'] if service && vm $evm.log('info', "XXXXXXXX Attaching Service to VM: [#{{service.name}}][#{{vm.name}}]") vm.add_to_service(service) vm.owner = user if user vm.group = user.miq_group if user end end $evm.log("info", "Listing Root Object Attributes:") $evm.log("info", "===========================================") add_to_service """.format(myservice.service_name) method = copy_domain\ .namespaces.instantiate(name='System')\ .classes.instantiate(name='Request')\ .methods.create(name='InspectMe', location='inline', script=method_torso) request.addfinalizer(method.delete_if_exists) simulate( instance="Request", message="create", request=method.name, attribute=["VM and Instance", "auto_test_services"], # Random selection, does not matter execute_methods=True ) myservice.check_vm_add("auto_test_services")
def test_automate_ansible_playbook_method_type(request, appliance, domain, namespace, klass, instance, method): """Tests execution an ansible playbook via ansible playbook method using Simulation. Polarion: assignee: sbulage casecomponent: Ansible caseimportance: medium initialEstimate: 1/4h """ simulate( appliance=appliance, request="Call_Instance", attributes_values={ "namespace": "{}/{}".format(domain.name, namespace.name), "class": klass.name, "instance": instance.name } ) request.addfinalizer(lambda: appliance.ssh_client.run_command( '[[ -f "/var/tmp/modified-release" ]] && rm -f "/var/tmp/modified-release"')) assert appliance.ssh_client.run_command('[ -f "/var/tmp/modified-release" ]').success
def test_automate_ansible_playbook_method_type(request, appliance, domain, namespace, klass, instance, method): """Tests execution an ansible playbook via ansible playbook method using Simulation. Polarion: assignee: dmisharo casecomponent: Ansible caseimportance: medium initialEstimate: 1/4h """ simulate( appliance=appliance, request="Call_Instance", attributes_values={ "namespace": "{}/{}".format(domain.name, namespace.name), "class": klass.name, "instance": instance.name } ) request.addfinalizer(lambda: appliance.ssh_client.run_command( '[[ -f "/var/tmp/modified-release" ]] && rm -f "/var/tmp/modified-release"')) assert appliance.ssh_client.run_command('[ -f "/var/tmp/modified-release" ]').success
def test_automate_generic_object_service_associations( appliance, klass, go_service_request, generic_object_definition): """ Polarion: assignee: dgaikwad initialEstimate: 1/10h caseimportance: medium startsin: 5.7 casecomponent: Automate Bugzilla: 1410920 """ schema_field = fauxfactory.gen_alphanumeric() # Ruby code script = 'go_class = $evm.vmdb(:generic_object_definition).find_by(:name => "{name}")\n'.format( name=generic_object_definition.name) script = script + ( 'load_balancer = go_class.create_object(:name => "Test Load Balancer", :location => ' '"Mahwah")\n' '$evm.log("info", "XYZ go object: #{load_balancer.inspect}")\n' 'service = $evm.vmdb(:service).first\n' 'load_balancer.services = [service]\n' 'content_type = "message"\n' 'load_balancer.save!\n' '$evm.log("info", "XYZ load balancer got service: #{load_balancer.services.first.inspect}")' '\nexit MIQ_OK') with appliance.context.use(ViaUI): # Adding schema for executing method klass.schema.add_fields({ 'name': schema_field, 'type': 'Method', 'data_type': 'String' }) # Adding method method = klass.methods.create( name=fauxfactory.gen_alphanumeric(), display_name=fauxfactory.gen_alphanumeric(), location='inline', script=script) # Adding instance to call automate method instance = klass.instances.create( name=fauxfactory.gen_alphanumeric(), display_name=fauxfactory.gen_alphanumeric(), description=fauxfactory.gen_alphanumeric(), fields={schema_field: { 'value': method.name }}) result = LogValidator( "/var/www/miq/vmdb/log/automation.log", matched_patterns=[ r'.*XYZ go object: #<MiqAeServiceGenericObject.*', r'.*XYZ load balancer got service: #<MiqAeServiceService.*' ], ) result.start_monitoring() # Executing automate method using simulation simulate( appliance=klass.appliance, attributes_values={ "namespace": klass.namespace.name, "class": klass.name, "instance": instance.name, }, message="create", request="Call_Instance", execute_methods=True, ) assert result.validate(wait="60s")
def test_service_retirement_from_automate_method(request, generic_catalog_item, custom_instance): """ Bugzilla: 1700524 Polarion: assignee: ghubale initialEstimate: 1/8h caseposneg: positive startsin: 5.11 casecomponent: Automate testSteps: 1. Create service catalog item and order 2. Create a writeable domain and copy ManageIQ/System/Request to this domain 3. Create retire_automation_service instance and set meth5 to retire_automation_service. 4. Create retire_automation_service method with sample code given below: > service = $evm.root['service'] > $evm.log(:info, "create_retire_request for service #{service}") > request = $evm.execute(:create_retire_request, service) > $evm.log(:info, "Create request for create_retire_request #{request}") 5. Execute this method using simulation expectedResults: 1. Service provision request should be provisioned successfully 2. 3. 4. 5. Service should be retired successfully """ # Ordering catalog item and deleting request once service has been reached to 'Finished' state service_request = generic_catalog_item.appliance.rest_api.collections.service_templates.get( name=generic_catalog_item.name).action.order() request.addfinalizer(lambda: service_request.action.delete()) wait_for(lambda: service_request.request_state == "finished", fail_func=service_request.reload, timeout=180, delay=10) # Ruby code to execute create_retire_request script = dedent(""" service = $evm.root['service'] $evm.log(:info, 'create_retire_request for service #{service}') request = $evm.execute(:create_retire_request, service) $evm.log(:info, 'Create request for create_retire_request #{request}') """) instance = custom_instance(ruby_code=script) with LogValidator("/var/www/miq/vmdb/log/automation.log", matched_patterns=[ '.*Create request for create_retire_request.*' ]).waiting(timeout=120): # Executing automate method simulate( appliance=generic_catalog_item.appliance, target_type="Service", target_object=f"{generic_catalog_item.name}", message="create", request=f"{instance.name}", execute_methods=True, ) retire_request = generic_catalog_item.appliance.rest_api.collections.requests.get( description=f"Service Retire for: {generic_catalog_item.name}") wait_for(lambda: retire_request.request_state == "finished", fail_func=retire_request.reload, timeout=180, delay=10)
def test_automate_state_method(klass): """ You can pass methods as states compared to the old method of passing instances which had to be located in different classes. You use the METHOD:: prefix Polarion: assignee: dgaikwad casecomponent: Automate caseimportance: medium initialEstimate: 1/4h tags: automate startsin: 5.6 testSteps: 1. Create an automate class that has one state. 2. Create a method in the class, make the method output something recognizable in the logs 3. Create an instance inside the class, and as a Value for the state use: METHOD::method_name where method_name is the name of the method you created 4. Run a simulation, use Request / Call_Instance to call your state machine instance expectedResults: 1. Class created 2. Method created 3. Instance created 4. The method got called, detectable by grepping logs """ state = fauxfactory.gen_alpha() klass.schema.add_fields({'name': state, 'type': 'State'}) method = klass.methods.create( name=fauxfactory.gen_alphanumeric(), display_name=fauxfactory.gen_alphanumeric(), location='inline', script="""\n$evm.log(:info, "Hello from state method")""") instance = klass.instances.create( name=fauxfactory.gen_alphanumeric(), display_name=fauxfactory.gen_alphanumeric(), description=fauxfactory.gen_alphanumeric(), fields={state: { "value": f"METHOD::{method.name}" }}) result = LogValidator( "/var/www/miq/vmdb/log/automation.log", matched_patterns=[".*Hello from state method.*"], ) result.start_monitoring() simulate( appliance=klass.appliance, attributes_values={ "namespace": klass.namespace.name, "class": klass.name, "instance": instance.name, }, message="create", request="Call_Instance", execute_methods=True, ) assert result.validate()
def test_priority( request, appliance, original_method, original_instance, original_domain, copy_domain, original_method_write_data, copy_method_write_data, domain_collection): """This test checks whether method overriding works across domains with the aspect of priority. Prerequisities: * Pick a random file name. Steps: * If the picked file name exists on the appliance, delete it * Create two domains (one for the original method and one for copied method). * Create a method in ``System/Request`` (in original domain) containing the method code as in this testing module, with the file in the method being the file picked and you pick the contents you want to write to the file. * Set the domain order so the original domain is first. * Run the simulation on the ``Request/<method_name>`` with executing. * The file on appliance should contain the data as you selected. * Copy the method to the second (copy) domain. * Change the copied method so it writes different data. * Set the domain order so the copy domain is first. * Run the same simulation again. * Check the file contents, it should be the same as the content you entered last. * Then pick the domain order so the original domain is first. * Run the same simulation again. * The contents of the file should be the same as in the first case. Polarion: assignee: dmisharo casecomponent: Automate initialEstimate: 1/4h """ ssh_client = appliance.ssh_client ssh_client.run_command("rm -f {}".format(FILE_LOCATION)) domain_collection.set_order([original_domain]) # Default first # # FIRST SIMULATION # simulate( appliance=appliance, instance="Request", message="create", request=original_instance.name, execute_methods=True ) wait_for( lambda: ssh_client.run_command("cat {}".format(FILE_LOCATION)).success, num_sec=120, delay=0.5, message="wait for file to appear" ) request.addfinalizer(lambda: ssh_client.run_command("rm -f {}".format(FILE_LOCATION))) result = ssh_client.run_command("cat {}".format(FILE_LOCATION)) assert result.output.strip() == original_method_write_data ssh_client.run_command("rm -f {}".format(FILE_LOCATION)) # END OF FIRST SIMULATION # We've checked that the automate method works, so let's copy them to new domain original_method.copy_to(copy_domain) copied_method = (copy_domain .namespaces.instantiate(name='System') .classes.instantiate(name='Request') .methods.instantiate(name=original_method.name)) # Set up a different thing to write to the file with update(copied_method): copied_method.script = METHOD_TORSO.format(copy_method_write_data) # Set it as the first one domain_collection.set_order([copy_domain]) # And verify # # SECOND SIMULATION # simulate( appliance=appliance, instance="Request", message="create", request=original_instance.name, execute_methods=True ) wait_for( lambda: ssh_client.run_command("cat {}".format(FILE_LOCATION)).success, num_sec=120, delay=0.5, message="wait for file to appear" ) result = ssh_client.run_command("cat {}".format(FILE_LOCATION)) assert result.output.strip() == copy_method_write_data ssh_client.run_command("rm -f {}".format(FILE_LOCATION)) # END OF SECOND SIMULATION # And last shot, now again with default domain domain_collection.set_order([original_domain]) # And verify # # LAST SIMULATION # simulate( appliance=appliance, instance="Request", message="create", request=original_instance.name, execute_methods=True ) wait_for( lambda: ssh_client.run_command("cat {}".format(FILE_LOCATION)).success, num_sec=120, delay=0.5, message="wait for file to appear" ) result = ssh_client.run_command("cat {}".format(FILE_LOCATION)) assert result.output.strip() == original_method_write_data ssh_client.run_command("rm -f {}".format(FILE_LOCATION))
def test_priority(request, appliance, original_method, original_instance, original_domain, copy_domain, original_method_write_data, copy_method_write_data, domain_collection): """This test checks whether method overriding works across domains with the aspect of priority. Polarion: assignee: dgaikwad casecomponent: Automate caseimportance: medium initialEstimate: 1/4h tags: automate testSteps: 1.If the picked file name exists on the appliance, delete it 2.Create two domains (one for the original method and one for copied method). 3.Create a method in ``System/Request`` (in original domain) containing the method code as in this testing module, with the file in the method being the file picked and you pick the contents you want to write to the file. 4.Set the domain order so the original domain is first. 5.Run the simulation on the ``Request/<method_name>`` with executing. 6.The file on appliance should contain the data as you selected. 7.Copy the method to the second (copy) domain. 8.Change the copied method so it writes different data. 9.Set the domain order so the copy domain is first. 10.Run the same simulation again. 11.Check the file contents, it should be the same as the content you entered last. 12.Then pick the domain order so the original domain is first. 13.Run the same simulation again. 14.The contents of the file should be the same as in the first case. """ ssh_client = appliance.ssh_client ssh_client.run_command(f"rm -f {FILE_LOCATION}") domain_collection.set_order([original_domain]) # Default first # # FIRST SIMULATION # simulate(appliance=appliance, instance="Request", message="create", request=original_instance.name, execute_methods=True) wait_for(lambda: ssh_client.run_command(f"cat {FILE_LOCATION}").success, num_sec=120, delay=0.5, message="wait for file to appear") request.addfinalizer( lambda: ssh_client.run_command(f"rm -f {FILE_LOCATION}")) result = ssh_client.run_command(f"cat {FILE_LOCATION}") assert result.output.strip() == original_method_write_data ssh_client.run_command(f"rm -f {FILE_LOCATION}") # END OF FIRST SIMULATION # We've checked that the automate method works, so let's copy them to new domain original_method.copy_to(copy_domain) copied_method = (copy_domain.namespaces.instantiate( name='System').classes.instantiate(name='Request').methods.instantiate( name=original_method.name)) # Set up a different thing to write to the file with update(copied_method): copied_method.script = METHOD_TORSO.format(copy_method_write_data) # Set it as the first one domain_collection.set_order([copy_domain]) # And verify # # SECOND SIMULATION # simulate(appliance=appliance, instance="Request", message="create", request=original_instance.name, execute_methods=True) wait_for(lambda: ssh_client.run_command(f"cat {FILE_LOCATION}").success, num_sec=120, delay=0.5, message="wait for file to appear") result = ssh_client.run_command(f"cat {FILE_LOCATION}") assert result.output.strip() == copy_method_write_data ssh_client.run_command(f"rm -f {FILE_LOCATION}") # END OF SECOND SIMULATION # And last shot, now again with default domain domain_collection.set_order([original_domain]) # And verify # # LAST SIMULATION # simulate(appliance=appliance, instance="Request", message="create", request=original_instance.name, execute_methods=True) wait_for(lambda: ssh_client.run_command(f"cat {FILE_LOCATION}").success, num_sec=120, delay=0.5, message="wait for file to appear") result = ssh_client.run_command(f"cat {FILE_LOCATION}") assert result.output.strip() == original_method_write_data ssh_client.run_command(f"rm -f {FILE_LOCATION}")
def test_priority(request, appliance, original_method, original_instance, original_domain, copy_domain, original_method_write_data, copy_method_write_data, domain_collection): """This test checks whether method overriding works across domains with the aspect of priority. Prerequisities: * Pick a random file name. Steps: * If the picked file name exists on the appliance, delete it * Create two domains (one for the original method and one for copied method). * Create a method in ``System/Request`` (in original domain) containing the method code as in this testing module, with the file in the method being the file picked and you pick the contents you want to write to the file. * Set the domain order so the original domain is first. * Run the simulation on the ``Request/<method_name>`` with executing. * The file on appliance should contain the data as you selected. * Copy the method to the second (copy) domain. * Change the copied method so it writes different data. * Set the domain order so the copy domain is first. * Run the same simulation again. * Check the file contents, it should be the same as the content you entered last. * Then pick the domain order so the original domain is first. * Run the same simulation again. * The contents of the file should be the same as in the first case. """ ssh_client = appliance.ssh_client ssh_client.run_command("rm -f {}".format(FILE_LOCATION)) domain_collection.set_order([original_domain]) # Default first # # FIRST SIMULATION # simulate(instance="Request", message="create", request=original_instance.name, execute_methods=True) wait_for( lambda: ssh_client.run_command("cat {}".format(FILE_LOCATION))[0] == 0, num_sec=120, delay=0.5, message="wait for file to appear") request.addfinalizer( lambda: ssh_client.run_command("rm -f {}".format(FILE_LOCATION))) rc, stdout = ssh_client.run_command("cat {}".format(FILE_LOCATION)) assert stdout.strip() == original_method_write_data ssh_client.run_command("rm -f {}".format(FILE_LOCATION)) # END OF FIRST SIMULATION # We've checked that the automate method works, so let's copy them to new domain original_method.copy_to(copy_domain) copied_method = copy_domain\ .namespaces.instantiate(name='System')\ .classes.instantiate(name='Request')\ .methods.instantiate(name=original_method.name) # Set up a different thing to write to the file with update(copied_method): copied_method.script = METHOD_TORSO.format(copy_method_write_data) # Set it as the first one domain_collection.set_order([copy_domain]) # And verify # # SECOND SIMULATION # simulate(instance="Request", message="create", request=original_instance.name, execute_methods=True) wait_for( lambda: ssh_client.run_command("cat {}".format(FILE_LOCATION))[0] == 0, num_sec=120, delay=0.5, message="wait for file to appear") rc, stdout = ssh_client.run_command("cat {}".format(FILE_LOCATION)) assert stdout.strip() == copy_method_write_data ssh_client.run_command("rm -f {}".format(FILE_LOCATION)) # END OF SECOND SIMULATION # And last shot, now again with default domain domain_collection.set_order([original_domain]) # And verify # # LAST SIMULATION # simulate(instance="Request", message="create", request=original_instance.name, execute_methods=True) wait_for( lambda: ssh_client.run_command("cat {}".format(FILE_LOCATION))[0] == 0, num_sec=120, delay=0.5, message="wait for file to appear") rc, stdout = ssh_client.run_command("cat {}".format(FILE_LOCATION)) assert stdout.strip() == original_method_write_data ssh_client.run_command("rm -f {}".format(FILE_LOCATION))
def test_priority( request, ssh_client, original_method, original_instance, copy_domain, original_method_write_data, copy_method_write_data): ssh_client.run_command("rm -f {}".format(FILE_LOCATION)) set_domain_order([Domain.default.name]) # Default first # # FIRST SIMULATION # simulate( instance="Request", message="create", request=original_instance.name, attribute=None, # Random selection, does not matter execute_methods=True ) wait_for( lambda: ssh_client.run_command("cat {}".format(FILE_LOCATION))[0] == 0, num_sec=120, delay=0.5, message="wait for file to appear" ) request.addfinalizer(lambda: ssh_client.run_command("rm -f {}".format(FILE_LOCATION))) rc, stdout = ssh_client.run_command("cat {}".format(FILE_LOCATION)) assert stdout.strip() == original_method_write_data ssh_client.run_command("rm -f {}".format(FILE_LOCATION)) # END OF FIRST SIMULATION # We've checked that the automate method works, so let's copy them to new domain copied_method = original_method.copy_to(copy_domain) request.addfinalizer(lambda: copied_method.delete()) copied_instance = original_instance.copy_to(copy_domain) request.addfinalizer(lambda: copied_instance.delete()) # Set up a different thing to write to the file with update(copied_method): copied_method.data = METHOD_TORSO.format(copy_method_write_data) # Set it as the first one set_domain_order([copy_domain.name]) # And verify # # SECOND SIMULATION # simulate( instance="Request", message="create", request=copied_instance.name, attribute=None, # Random selection, does not matter execute_methods=True ) wait_for( lambda: ssh_client.run_command("cat {}".format(FILE_LOCATION))[0] == 0, num_sec=120, delay=0.5, message="wait for file to appear" ) rc, stdout = ssh_client.run_command("cat {}".format(FILE_LOCATION)) assert stdout.strip() == copy_method_write_data ssh_client.run_command("rm -f {}".format(FILE_LOCATION)) # END OF SECOND SIMULATION # And last shot, now again with default domain set_domain_order([Domain.default.name]) # And verify # # LAST SIMULATION # simulate( instance="Request", message="create", request=original_instance.name, attribute=None, # Random selection, does not matter execute_methods=True ) wait_for( lambda: ssh_client.run_command("cat {}".format(FILE_LOCATION))[0] == 0, num_sec=120, delay=0.5, message="wait for file to appear" ) rc, stdout = ssh_client.run_command("cat {}".format(FILE_LOCATION)) assert stdout.strip() == original_method_write_data ssh_client.run_command("rm -f {}".format(FILE_LOCATION))
def test_send_email_method(smtp_test, klass): """ Polarion: assignee: ghubale initialEstimate: 1/20h startsin: 5.10 casecomponent: Automate Bugzilla: 1688500 1702304 """ mail_to = fauxfactory.gen_email() mail_cc = fauxfactory.gen_email() mail_bcc = fauxfactory.gen_email() # Ruby code to send emails script = ( 'to = "{mail_to}"\n' 'subject = "Hello"\n' 'body = "Hi"\n' 'bcc = "{mail_bcc}"\n' 'cc = "{mail_cc}"\n' 'content_type = "message"\n' 'from = "*****@*****.**"\n' "$evm.execute(:send_email, to, from, subject, body, {{:bcc => bcc, :cc => cc," ":content_type => content_type}})" ) script = script.format(mail_cc=mail_cc, mail_bcc=mail_bcc, mail_to=mail_to) # Adding schema for executing method - send_email which helps to send emails klass.schema.add_fields({'name': 'execute', 'type': 'Method', 'data_type': 'String'}) # Adding method - send_email for sending mails method = klass.methods.create( name=fauxfactory.gen_alphanumeric(), display_name=fauxfactory.gen_alphanumeric(), location='inline', script=script) # Adding instance to call automate method - send_email instance = klass.instances.create( name=fauxfactory.gen_alphanumeric(), display_name=fauxfactory.gen_alphanumeric(), description=fauxfactory.gen_alphanumeric(), fields={'execute': {'value': method.name}} ) result = LogValidator( "/var/www/miq/vmdb/log/evm.log", matched_patterns=[ '.*:to=>"{mail_to}".*.*:cc=>"{mail_cc}".*.*:bcc=>"{mail_bcc}".*'.format( mail_to=mail_to, mail_cc=mail_cc, mail_bcc=mail_bcc ) ], ) result.fix_before_start() # Executing automate method - send_email using simulation simulate( appliance=klass.appliance, attributes_values={ "namespace": klass.namespace.name, "class": klass.name, "instance": instance.name, }, message="create", request="Call_Instance", execute_methods=True, ) result.validate_logs() # TODO(GH-8820): This issue should be fixed to check mails sent to person in 'cc' and 'bcc' # Check whether the mail sent via automate method really arrives wait_for(lambda: len(smtp_test.get_emails(to_address=mail_to)) > 0, num_sec=60, delay=10)
def test_priority( request, ssh_client, original_method, original_instance, original_domain, copy_domain, original_method_write_data, copy_method_write_data): """This test checks whether method overriding works across domains with the aspect of priority. Prerequisities: * Pick a random file name. Steps: * If the picked file name exists on the appliance, delete it * Create two domains (one for the original method and one for copied method). * Create a method in ``System/Request`` (in original domain) containing the method code as in this testing module, with the file in the method being the file picked and you pick the contents you want to write to the file. * Set the domain order so the original domain is first. * Run the simulation on the ``Request/<method_name>`` with executing. * The file on appliance should contain the data as you selected. * Copy the method to the second (copy) domain. * Change the copied method so it writes different data. * Set the domain order so the copy domain is first. * Run the same simulation again. * Check the file contents, it should be the same as the ćontent you entered last. * Then pick the domain order so the original domain is first. * Run the same simulation again. * The contents of the file should be the same as in the first case. """ ssh_client.run_command("rm -f {}".format(FILE_LOCATION)) set_domain_order([original_domain.name]) # Default first # # FIRST SIMULATION # simulate( instance="Request", message="create", request=original_instance.name, attribute=None, # Random selection, does not matter execute_methods=True ) wait_for( lambda: ssh_client.run_command("cat {}".format(FILE_LOCATION))[0] == 0, num_sec=120, delay=0.5, message="wait for file to appear" ) request.addfinalizer(lambda: ssh_client.run_command("rm -f {}".format(FILE_LOCATION))) rc, stdout = ssh_client.run_command("cat {}".format(FILE_LOCATION)) assert stdout.strip() == original_method_write_data ssh_client.run_command("rm -f {}".format(FILE_LOCATION)) # END OF FIRST SIMULATION # We've checked that the automate method works, so let's copy them to new domain copied_method = original_method.copy_to(copy_domain) request.addfinalizer(copied_method.delete) # Set up a different thing to write to the file with update(copied_method): copied_method.data = METHOD_TORSO.format(copy_method_write_data) # Set it as the first one set_domain_order([copy_domain.name]) # And verify # # SECOND SIMULATION # simulate( instance="Request", message="create", request=original_instance.name, attribute=None, # Does not matter execute_methods=True ) wait_for( lambda: ssh_client.run_command("cat {}".format(FILE_LOCATION))[0] == 0, num_sec=120, delay=0.5, message="wait for file to appear" ) rc, stdout = ssh_client.run_command("cat {}".format(FILE_LOCATION)) assert stdout.strip() == copy_method_write_data ssh_client.run_command("rm -f {}".format(FILE_LOCATION)) # END OF SECOND SIMULATION # And last shot, now again with default domain set_domain_order([original_domain.name]) # And verify # # LAST SIMULATION # simulate( instance="Request", message="create", request=original_instance.name, attribute=None, # Does not matter execute_methods=True ) wait_for( lambda: ssh_client.run_command("cat {}".format(FILE_LOCATION))[0] == 0, num_sec=120, delay=0.5, message="wait for file to appear" ) rc, stdout = ssh_client.run_command("cat {}".format(FILE_LOCATION)) assert stdout.strip() == original_method_write_data ssh_client.run_command("rm -f {}".format(FILE_LOCATION))
def test_automate_simulate_retry(klass, domain, namespace, original_class): """Automate simulation now supports simulating the state machines. Polarion: assignee: ghubale initialEstimate: 1/4h caseimportance: medium caseposneg: positive testtype: functional startsin: 5.6 casecomponent: Automate tags: automate title: Test automate simulate retry setup: 1. Create a state machine that contains a couple of states testSteps: 1. Create an Automate model that has a State Machine that can end in a retry 2. Run a simulation to test the Automate Model from Step 1 3. When the Automation ends in a retry, we should be able to resubmit the request 4. Use automate simulation UI to call the state machine (Call_Instance) expectedResults: 1. 2. 3. 4. A Retry button should appear. Bugzilla: 1299579 """ # Adding schema for running 'RETRY' method klass.schema.add_fields({'name': 'RUN', 'type': 'Method', 'data_type': 'String'}) # Adding 'RETRY' method method = klass.methods.create( name=fauxfactory.gen_alphanumeric(), display_name=fauxfactory.gen_alphanumeric(), location='inline', script='''root = $evm.root \n if root['ae_state_retries'] && root['ae_state_retries'] > 2 \n \t \t root['ae_result'] = 'ok'\n else \t \t root['ae_result'] = 'retry' \n end''', ) # Adding 'RETRY_METHOD' instance to call 'RETRY' method instance = klass.instances.create( name=fauxfactory.gen_alphanumeric(), display_name=fauxfactory.gen_alphanumeric(), description=fauxfactory.gen_alphanumeric(), fields={'RUN': {'value': method.name}} ) # Creating new class in same domain/namespace new_class = namespace.collections.classes.create(name=fauxfactory.gen_alphanumeric()) # Creating schema of new class with 'TYPE' - 'State' new_class.schema.add_fields({'name': 'STATE1', 'type': 'State', 'data_type': 'String'}) # Adding new instance - 'TEST_RETRY' to new class which calls instance - 'RETRY_METHOD' new_instance = new_class.instances.create( name=fauxfactory.gen_alphanumeric(), display_name=fauxfactory.gen_alphanumeric(), description=fauxfactory.gen_alphanumeric(), fields={ "STATE1": { "value": "/{domain}/{namespace}/{klass}/{instance}".format( domain=domain.name, namespace=namespace.name, klass=klass.name, instance=instance.name, ) } }, ) # Creating instance 'MY_TEST' under original class which uses relationship - 'rel1' of schema to # call new_instance - 'TEST_RETRY' original_instance = original_class.instances.create( name=fauxfactory.gen_alphanumeric(), fields={ "rel1": { "value": "/{domain}/{namespace}/{klass}/{instance}".format( domain=domain.name, namespace=namespace.name, klass=new_class.name, instance=new_instance.name, ) } }, ) # Navigating to 'AutomateSimulation' view to check whether retry button is not available before # executing automate method view = navigate_to(klass.appliance.server, 'AutomateSimulation') assert not view.retry_button.is_displayed # Executing automate method - 'RETRY' using simulation simulate( appliance=klass.appliance, instance="Request", message="create", request=original_instance.name, execute_methods=True ) # Checking whether 'Retry' button is displayed assert view.retry_button.is_displayed
def test_generate_widget_content_by_automate(request, appliance, klass, namespace, domain): """ Polarion: assignee: ghubale initialEstimate: 1/8h caseimportance: medium caseposneg: positive testtype: functional startsin: 5.10 casecomponent: Automate tags: automate testSteps: 1. create a new widget and add this widget to dashboard 2. Create automate method with below content: # # Description: generate widget content by calling shell command # cmd =("/var/www/miq/vmdb/bin/rails r 'MiqWidget.find_by_title(\"widget_name\").queue_generate_content'") system(cmd) exit MIQ_OK 3. Execute the automate method(by simulation) and check updated time of that widget on dashboard. 4. Updated status changes once we trigger the generation of a widget content from Automate method. 5. Or we can check widget status by executing following commands on rails console: >> MiqWidget.find_by_title("widget_name") >> service_miq_widget = MiqAeMethodService::MiqAeServiceMiqWidget.find(widget_id) >> service_miq_widget.queue_generate_content (this will do same what we did with automate method) expectedResults: 1. 2. 3. Updated time of that widget on dashboard should be changes to current time of update by automate method. 4. 5. Updated time of that widget on dashboard should be changes to current time of update by rails. Bugzilla: 1445932 """ widget_name = fauxfactory.gen_alphanumeric() schema_field = fauxfactory.gen_alphanumeric() # Added method with given code method = klass.methods.create( name=fauxfactory.gen_alphanumeric(), display_name=fauxfactory.gen_alphanumeric(), location='inline', script="""cmd =('/var/www/miq/vmdb/bin/rails r \ "MiqWidget.find_by_title(\\'{widget}\\').queue_generate_content"')\nsystem(cmd)\n exit MIQ_OK""".format(widget=widget_name)) # Edited schema of class to execute method using instance klass.schema.add_fields({ 'name': schema_field, 'type': 'Method', 'data_type': 'String' }) # Added new instance instance = klass.instances.create( name=fauxfactory.gen_alphanumeric(), fields={schema_field: { 'value': method.name }}) # Created chart widget widget = appliance.collections.dashboard_report_widgets.create( appliance.collections.dashboard_report_widgets.CHART, widget_name, description=fauxfactory.gen_alphanumeric(), active=True, filter="Configuration Management/Virtual Machines/Vendor and Guest OS", timer={ "run": "Hourly", "hours": "Hour" }, visibility="<To All Users>") request.addfinalizer(widget.delete) # Added newly created widget to dashboard view = widget.create_view(AllDashboardWidgetsView) view.flash.assert_message(f'Widget "{widget.title}" was saved') view = navigate_to(appliance.server, 'Dashboard') view.add_widget.item_select(widget.title) # Browser refresh to get update status of widget otherwise it gives None view = navigate_to(widget, 'Details') old_update = view.last_run_time.read().split(' ')[4] # Executed automate method using simulation simulate(appliance=appliance, request='Call_Instance', attributes_values={ 'namespace': '{domain}/{namespace}'.format(domain=domain.name, namespace=namespace.name), 'class': klass.name, 'instance': instance.name }) # Refreshing widget to get current updated time widget.refresh() current_update = view.last_run_time.read().split(' ')[4] assert old_update != current_update
def test_generate_widget_content_by_automate(request, appliance, klass, namespace, domain): """ Polarion: assignee: ghubale initialEstimate: 1/8h caseimportance: medium caseposneg: positive testtype: functional startsin: 5.10 casecomponent: Automate tags: automate testSteps: 1. create a new widget and add this widget to dashboard 2. Create automate method with below content: # # Description: generate widget content by calling shell command # cmd =("/var/www/miq/vmdb/bin/rails r 'MiqWidget.find_by_title(\"widget_name\").queue_generate_content'") system(cmd) exit MIQ_OK 3. Execute the automate method(by simulation) and check updated time of that widget on dashboard. 4. Updated status changes once we trigger the generation of a widget content from Automate method. 5. Or we can check widget status by executing following commands on rails console: >> MiqWidget.find_by_title("widget_name") >> service_miq_widget = MiqAeMethodService::MiqAeServiceMiqWidget.find(widget_id) >> service_miq_widget.queue_generate_content (this will do same what we did with automate method) expectedResults: 1. 2. 3. Updated time of that widget on dashboard should be changes to current time of update by automate method. 4. 5. Updated time of that widget on dashboard should be changes to current time of update by rails. Bugzilla: 1445932 """ widget_name = fauxfactory.gen_alphanumeric() # Added method with given code method = klass.methods.create( name=fauxfactory.gen_alphanumeric(), display_name=fauxfactory.gen_alphanumeric(), location='inline', script="""cmd =('/var/www/miq/vmdb/bin/rails r \ "MiqWidget.find_by_title(\\'{widget}\\').queue_generate_content"')\nsystem(cmd)\n exit MIQ_OK""".format(widget=widget_name) ) # Edited schema of class to execute method using instance klass.schema.add_fields({'name': 'execute', 'type': 'Method', 'data_type': 'String'}) # Added new instance instance = klass.instances.create( name=fauxfactory.gen_alphanumeric(), fields={'execute': {'value': '{method}'.format(method=method.name)}} ) # Created chart widget widget = appliance.collections.dashboard_report_widgets.create( appliance.collections.dashboard_report_widgets.CHART, widget_name, description=fauxfactory.gen_alphanumeric(), active=True, filter="Configuration Management/Virtual Machines/Vendor and Guest OS", timer={"run": "Hourly", "hours": "Hour"}, visibility="<To All Users>" ) request.addfinalizer(widget.delete) # Added newly created widget to dashboard view = widget.create_view(AllDashboardWidgetsView) view.flash.assert_message('Widget "{title}" was saved'.format(title=widget.title)) view = navigate_to(appliance.server, 'Dashboard') view.add_widget.item_select(widget.title) # Browser refresh to get update status of widget otherwise it gives None view = navigate_to(widget, 'Details') old_update = view.last_run_time.read().split(' ')[4] # Executed automate method using simulation simulate( appliance=appliance, request='Call_Instance', attributes_values={ 'namespace': '{domain}/{namespace}'.format(domain=domain.name, namespace=namespace.name), 'class': klass.name, 'instance': instance.name } ) # Refreshing widget to get current updated time widget.refresh() current_update = view.last_run_time.read().split(' ')[4] assert old_update != current_update
def test_automate_simulate_retry(klass, domain, namespace, original_class): """Automate simulation now supports simulating the state machines. Polarion: assignee: dgaikwad initialEstimate: 1/4h caseimportance: medium caseposneg: positive testtype: functional startsin: 5.6 casecomponent: Automate tags: automate setup: 1. Create a state machine that contains a couple of states testSteps: 1. Create an Automate model that has a State Machine that can end in a retry 2. Run a simulation to test the Automate Model from Step 1 3. When the Automation ends in a retry, we should be able to resubmit the request 4. Use automate simulation UI to call the state machine (Call_Instance) expectedResults: 1. 2. 3. 4. A Retry button should appear. Bugzilla: 1299579 """ # Adding schema for running 'RETRY' method klass.schema.add_fields({ 'name': 'RUN', 'type': 'Method', 'data_type': 'String' }) # Adding 'RETRY' method method = klass.methods.create( name=fauxfactory.gen_alphanumeric(), display_name=fauxfactory.gen_alphanumeric(), location='inline', script='''root = $evm.root \n if root['ae_state_retries'] && root['ae_state_retries'] > 2 \n \t \t root['ae_result'] = 'ok'\n else \t \t root['ae_result'] = 'retry' \n end''', ) # Adding 'RETRY_METHOD' instance to call 'RETRY' method instance = klass.instances.create( name=fauxfactory.gen_alphanumeric(), display_name=fauxfactory.gen_alphanumeric(), description=fauxfactory.gen_alphanumeric(), fields={'RUN': { 'value': method.name }}) # Creating new class in same domain/namespace new_class = namespace.collections.classes.create( name=fauxfactory.gen_alphanumeric()) # Creating schema of new class with 'TYPE' - 'State' new_class.schema.add_fields({ 'name': 'STATE1', 'type': 'State', 'data_type': 'String' }) # Adding new instance - 'TEST_RETRY' to new class which calls instance - 'RETRY_METHOD' new_instance = new_class.instances.create( name=fauxfactory.gen_alphanumeric(), display_name=fauxfactory.gen_alphanumeric(), description=fauxfactory.gen_alphanumeric(), fields={ "STATE1": { "value": "/{domain}/{namespace}/{klass}/{instance}".format( domain=domain.name, namespace=namespace.name, klass=klass.name, instance=instance.name, ) } }, ) # Creating instance 'MY_TEST' under original class which uses relationship - 'rel1' of schema to # call new_instance - 'TEST_RETRY' original_instance = original_class.instances.create( name=fauxfactory.gen_alphanumeric(), fields={ "rel1": { "value": "/{domain}/{namespace}/{klass}/{instance}".format( domain=domain.name, namespace=namespace.name, klass=new_class.name, instance=new_instance.name, ) } }, ) # Navigating to 'AutomateSimulation' view to check whether retry button is not available before # executing automate method view = navigate_to(klass.appliance.server, 'AutomateSimulation') assert not view.retry_button.is_displayed # Executing automate method - 'RETRY' using simulation simulate(appliance=klass.appliance, instance="Request", message="create", request=original_instance.name, execute_methods=True) # Checking whether 'Retry' button is displayed assert view.retry_button.is_displayed
def test_null_coalescing_fields(request, klass): """ Bugzilla: 1698184 Polarion: assignee: dgaikwad initialEstimate: 1/8h caseimportance: high caseposneg: positive testtype: functional startsin: 5.10 casecomponent: Automate tags: automate testSteps: 1. Create a Ruby method or Ansible playbook method with Input Parameters. 2. Use Data Type null coalescing 3. Make the default value something like this : ${#var3} || ${#var2} || ${#var1} expectedResults: 1. 2. 3. Normal null coalescing behavior """ var1, var2, var3, var4 = [fauxfactory.gen_alpha() for _ in range(4)] klass.schema.add_fields(*[{ "name": var, "type": var_type, "data_type": "String", "default_value": value, } for var, value, var_type in [ [var1, "fred", "Attribute"], [var2, "george", "Attribute"], [var3, " ", "Attribute"], [var4, "", "Method"], ]]) method = klass.methods.create( name=fauxfactory.gen_alphanumeric(), location="inline", script=dedent(""" $evm.log(:info, "Hello world") """), inputs={ "arg1": { "data_type": "null coalescing", "default_value": "".join(('${#', var1, '} ||${#', var2, '} ||${#', var3, '}')) }, "arg2": { "data_type": "null coalescing", "default_value": "".join(('${#', var2, '} ||${#', var1, '} ||${#', var3, '}')) }, }, ) request.addfinalizer(method.delete_if_exists) instance = klass.instances.create( name=fauxfactory.gen_alphanumeric(), description=fauxfactory.gen_alphanumeric(), fields={var4: { "value": method.name }}) request.addfinalizer(instance.delete_if_exists) log = LogValidator( "/var/www/miq/vmdb/log/automation.log", matched_patterns=[ r'.*\[{\"arg1\"=>\"fred\", \"arg2\"=>\"george\"}\].*' ], ) log.start_monitoring() # Executing automate method using simulation simulate( appliance=instance.klass.appliance, message="create", request="Call_Instance", execute_methods=True, attributes_values={ "namespace": instance.klass.namespace.name, "class": instance.klass.name, "instance": instance.name, }, ) assert log.validate()
def test_state_machine_variable(klass): """ Test whether storing the state machine variable works and the value is available in another state. Polarion: assignee: dgaikwad casecomponent: Automate caseimportance: medium initialEstimate: 1/4h tags: automate """ schema_field1, schema_field2, state_var = [fauxfactory.gen_alpha() for i in range(3)] script1 = dedent( f""" $evm.set_state_var(:var1, "{state_var}") """ ) script2 = dedent( """ state_value = $evm.get_state_var(:var1) $evm.log('info', "Value of state var returned #{state_value}") """ ) klass.schema.add_fields( *[ {"name": field, "type": "State", "data_type": "String"} for field in [schema_field1, schema_field2] ] ) methods = list( map( lambda script: klass.methods.create( name=fauxfactory.gen_alphanumeric(), location="inline", script=script ), [script1, script2], ) ) instance = klass.instances.create( name=fauxfactory.gen_alphanumeric(), display_name=fauxfactory.gen_alphanumeric(), description=fauxfactory.gen_alphanumeric(), fields={schema_field1: {"value": f"METHOD::{methods[0].name}"}, schema_field2: {"value": f"METHOD::{methods[1].name}"}}, ) with LogValidator( "/var/www/miq/vmdb/log/automation.log", matched_patterns=[f'.*Value of state var returned {state_var}.*'], ).waiting(timeout=120): # Executing automate method simulate( appliance=klass.appliance, attributes_values={ "namespace": klass.namespace.name, "class": klass.name, "instance": instance.name, }, message="create", request="Call_Instance", execute_methods=True, )
def test_method_for_log_and_notify(request, klass, notify_level, log_level): """ PR: https://github.com/ManageIQ/manageiq-content/pull/423 https://github.com/ManageIQ/manageiq-content/pull/362 Polarion: assignee: dgaikwad initialEstimate: 1/8h startsin: 5.9 casecomponent: Automate testSteps: 1. Create a new Automate Method 2. In the Automate Method screen embed ManageIQ/System/CommonMethods/Utils/log_object you can pick this method from the UI tree picker 3. In your method add a line akin to ManageIQ::Automate::System::CommonMethods::Utils::LogObject.log_and_notify (:info, "Hello Testing Log & Notify", $evm.root['vm'], $evm) 4. Check the logs and In your UI session you should see a notification """ schema_name = fauxfactory.gen_alpha() # Adding schema for executing method klass.schema.add_fields({ 'name': schema_name, 'type': 'Method', 'data_type': 'String' }) request.addfinalizer(lambda: klass.schema.delete_field(schema_name)) # Adding automate method with embedded method method = klass.methods.create( name=fauxfactory.gen_alphanumeric(), display_name=fauxfactory.gen_alphanumeric(), location='inline', embedded_method=("Datastore", "ManageIQ (Locked)", "System", "CommonMethods", "Utils", "log_object"), script=''' \nManageIQ::Automate::System::CommonMethods::Utils::LogObject.log_ar_objects() \nManageIQ::Automate::System::CommonMethods::Utils::LogObject.current() \nManageIQ::Automate::System::CommonMethods::Utils::LogObject.log_and_notify({}, "Hello Testing Log & Notify", $evm.root['vm'], $evm) '''.format(notify_level)) request.addfinalizer(method.delete_if_exists) # Adding instance to call automate method instance = klass.instances.create( name=fauxfactory.gen_alphanumeric(), display_name=fauxfactory.gen_alphanumeric(), description=fauxfactory.gen_alphanumeric(), fields={schema_name: { 'value': method.name }}) request.addfinalizer(instance.delete_if_exists) result = LogValidator( "/var/www/miq/vmdb/log/automation.log", matched_patterns=[ f".*Validating Notification type: automate_user_{log_level}.*", f".*Calling Create Notification type: automate_user_{log_level}.*", ".*Hello Testing Log & Notify.*" ], failure_patterns=[".*ERROR.*"]) result.start_monitoring() # Executing automate method using simulation simulate(appliance=klass.appliance, message="create", request="Call_Instance", execute_methods=True, attributes_values={ "namespace": klass.namespace.name, "class": klass.name, "instance": instance.name, }) if log_level == "error": with pytest.raises( FailPatternMatchError, match= "Pattern '.*ERROR.*': Expected failure pattern found in log."): result.validate(wait="60s") else: result.validate(wait="60s")
def test_miq_stop_abort_with_state_machines(request, setup, process, domain, klass, namespace): """ Bugzilla: 1441353 Polarion: assignee: ghubale initialEstimate: 1/8h caseimportance: high caseposneg: positive testtype: functional startsin: 5.9 casecomponent: Automate tags: automate setup: 1. Create automate domain, namespace, two classes - class A and class B 2. Class A and B should have schema of type - State 3. Create instance A1 and method A1 under class A. Here instance A1 should call method A1 4. Create two instances B1, B2 and three methods B1, B2, B3 under class B. Here instance B1 should call two methods B1 and B2. Also instance B2 should call method B3 5. Now Update instance A1 to call instance B1 and B2 testSteps: 1. Navigate to Automation > Automate > Simulation page and execute instance A1 2. If all the methods contain process - MIQ_STOP 3. If any method(in this test case - method B1, B2, B3) contains process - MIQ_ABORT expectedResults: 1. 2. MIQ_STOP process only stops execution of current instance but it allows state machine to execute other instances. So we are able to see execution of prent method - method A1 - "Hello from method of parent instance" 3. MIQ_ABORT process stops execution of current instance as well as its parent instance (here it stops instance B1 and then instance A1) which leads to no execution parent instances - instance A1. So we are not able to see execution of parent method - method A1 - "Hello from method of parent instance" """ klass2, instance, state1, state2, state3 = setup # Creating three child methods to execute via child instances child_method = list(map(lambda num: klass2.methods.create( name=fauxfactory.gen_alphanumeric(), display_name=fauxfactory.gen_alphanumeric(), location='inline', script=f""" \n$evm.log(:info, "This is method {num}") \nexit {process.upper()} """ ), ["first", "second", "third"])) fields = [{state1: {'value': f"METHOD::{child_method[0].name}"}, state2: {'value': f"METHOD::{child_method[1].name}"}}, {state1: {'value': f"METHOD::{child_method[2].name}"}}] # Creating two child instances child_inst = list(map(lambda field: klass2.instances.create( name=fauxfactory.gen_alphanumeric(), display_name=fauxfactory.gen_alphanumeric(), description=fauxfactory.gen_alphanumeric(), fields=field ), fields)) @request.addfinalizer def finalize(): for method in child_method: method.delete_if_exists() for inst in child_inst: inst.delete_if_exists() # Updating parent instance fields to execute child instances with update(instance): instance.fields = { state1: { "value": f"/{domain.name}/{namespace.name}/{klass2.name}/{child_inst[0].name}" }, state2: { "value": f"/{domain.name}/{namespace.name}/{klass2.name}/{child_inst[1].name}" }, } result = LogValidator( "/var/www/miq/vmdb/log/automation.log", matched_patterns=[".*Hello from method of parent instance.*"], ) result.start_monitoring() # Executing state machine simulate( appliance=klass.appliance, attributes_values={ "namespace": klass.namespace.name, "class": klass.name, "instance": instance.name, }, message="create", request="Call_Instance", execute_methods=True, ) if process == "miq_abort": assert not result.validate() else: assert result.validate()
def test_automate_relationship_trailing_spaces(request, klass, namespace, domain): """ Handle trailing whitespaces in automate instance relationships. Polarion: assignee: ghubale initialEstimate: 1/10h caseimportance: medium caseposneg: positive testtype: functional startsin: 5.9 casecomponent: Automate tags: automate title: Test automate relationship trailing spaces testSteps: 1. Create a class and its instance, also create second one, that has a relationship field. 2. Create an instance with the relationship field pointing to the first class' instance but add a couple of whitespaces after it. 3. Execute the AE model, eg. using Simulate. expectedResults: 1. 2. 3. Logs contain no resolution errors. PR: https://github.com/ManageIQ/manageiq/pull/7550 """ # Message to display in automation log by executing method of klass catch_string = fauxfactory.gen_alphanumeric() # Added method1 for klass1 method = klass.methods.create( name=fauxfactory.gen_alphanumeric(), location='inline', script='$evm.log(:info, "{}")'.format(catch_string) ) request.addfinalizer(method.delete_if_exists) # Added schema for klass1 with type method for calling the method1 in same klass1 klass.schema.add_fields({'name': 'meth', 'type': 'Method', 'data_type': 'String'}) # Created instance1 to execute method1 instance = klass.instances.create( name=fauxfactory.gen_alphanumeric(), display_name=fauxfactory.gen_alphanumeric(), description=fauxfactory.gen_alphanumeric(), fields={'meth': {'value': method.name}} ) request.addfinalizer(instance.delete_if_exists) # Created klass2 under same domain/namespace klass2 = namespace.classes.create( name=fauxfactory.gen_alpha(), display_name=fauxfactory.gen_alpha(), description=fauxfactory.gen_alpha() ) request.addfinalizer(klass2.delete_if_exists) # Added schema for klass2 with type Relationship for calling instance1 of klass1 klass2.schema.add_fields({'name': 'rel', 'type': 'Relationship', 'data_type': 'String'}) # Created instance2 of klass2 and called instance1 of klass1. Here couple of white spaces are # added in the value field of rel type. instance2 = klass2.instances.create( name=fauxfactory.gen_alphanumeric(), display_name=fauxfactory.gen_alphanumeric(), description=fauxfactory.gen_alphanumeric(), fields={ "rel": { "value": "/{domain}/{namespace}/{klass}/{instance} ".format( domain=domain.name, namespace=namespace.name, klass=klass.name, instance=instance.name, ) } }, ) request.addfinalizer(instance2.delete_if_exists) # Executing the automate method of klass1 using simulation simulate( appliance=klass.appliance, request="Call_Instance", attributes_values={ "namespace": "{}/{}".format(domain.name, namespace.name), "class": klass2.name, "instance": instance2.name, }, ) # Checking if automation log is giving resolution error or not by searching 'E,'. # Also checking if method1 of klass1 is executed successfully or not by searching 'catch_string' # in automation log. for search in ['E,', catch_string]: result = klass.appliance.ssh_client.run_command( "grep {} /var/www/miq/vmdb/log/automation.log".format(search) ) if search == 'E,': assert result.output == "" else: assert search in result.output