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
Example #2
0
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
Example #3
0
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,
        )
Example #4
0
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,
            },
        )
Example #6
0
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,
            },
        )
Example #7
0
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()
Example #8
0
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()
Example #9
0
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()
Example #10
0
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()
Example #11
0
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")
Example #13
0
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_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))
Example #18
0
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))
Example #19
0
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))
Example #21
0
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)
Example #25
0
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,
            },
        )
Example #26
0
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")
Example #31
0
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()
Example #33
0
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))
Example #34
0
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))
Example #37
0
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
Example #40
0
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
Example #41
0
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()
Example #44
0
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")
Example #46
0
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