Skip to content
This repository has been archived by the owner on Apr 7, 2022. It is now read-only.

[1LP][RFR]Automate: test_schedule_automation_request #9913

Merged
merged 1 commit into from
Feb 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 99 additions & 0 deletions cfme/automate/requests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import attr
from navmazing import NavigateToAttribute
from widgetastic.widget import Text
from widgetastic.widget import View
from widgetastic_patternfly import Button

from cfme.common import BaseLoggedInPage
from cfme.exceptions import RestLookupError
from cfme.modeling.base import BaseCollection
from cfme.modeling.base import BaseEntity
from cfme.services.requests import RequestsView
from cfme.utils.appliance.implementations.ui import CFMENavigateStep
from cfme.utils.appliance.implementations.ui import navigator
from widgetastic_manageiq import SummaryForm


@attr.s
class AutomationRequest(BaseEntity):
# TODO: Add more methods and properties as required, refer service `Request` entity

description = attr.ib(default=None)
message = attr.ib(default=None)

@property
def rest_api_entity(self):
try:
return self.appliance.rest_api.collections.automation_requests.get(
description=self.description
)
except ValueError:
raise RestLookupError(
f"No automation request rest entity found matching description '{self.description}'"
)


@attr.s
class AutomationRequestCollection(BaseCollection):
"""The appliance collection of requests"""

ENTITY = AutomationRequest


class AutomateRequestsToolbar(View):
"""Toolbar on the requests view"""

reload = Button(title="Refresh this page")
delete = Button(title="Delete this Request")


class AutomateRequestsView(RequestsView):
@property
def is_displayed(self):
return (
self.logged_in_as_current_user
and self.navigation.currently_selected == ["Automation", "Automate", "Requests"]
and self.title.text == "Requests"
)


class AutomateRequestsDetailsView(BaseLoggedInPage):
title = Text('//div[@id="main-content"]//h1')
toolbar = View.nested(AutomateRequestsToolbar)

@View.nested
class details(View): # noqa
request_details = SummaryForm("Request Details")

@View.nested
class automations_tasks(View):
# TODO: Add a widget for Automations Tasks
pass

@property
def is_displayed(self):
description = self.context["object"].description
return (
self.logged_in_as_current_user
and self.navigation.currently_selected == ["Automation", "Automate", "Requests"]
and self.title.text == description
and self.breadcrumb.active_location == description
)


@navigator.register(AutomationRequestCollection, "All")
class AutomateRequestsAll(CFMENavigateStep):
VIEW = AutomateRequestsView
prerequisite = NavigateToAttribute("appliance.server", "LoggedIn")

def step(self, *args, **kwargs):
self.prerequisite_view.navigation.select("Automation", "Automate", "Requests")


@navigator.register(AutomationRequest, "Details")
class AutomateRequestsDetails(CFMENavigateStep):
VIEW = AutomateRequestsDetailsView
prerequisite = NavigateToAttribute("parent", "All")

def step(self, *args, **kwargs):
return self.prerequisite_view.table.row(description=self.obj.description).click()
96 changes: 94 additions & 2 deletions cfme/tests/automate/test_rest.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
"""REST API specific automate tests."""
from datetime import datetime

import fauxfactory
import pytest
from dateparser import parse

from cfme import test_requirements
from cfme.utils.appliance.implementations.ui import navigate_to
from cfme.utils.blockers import BZ
from cfme.utils.rest import assert_response
from cfme.utils.rest import delete_resources_from_collection
from cfme.utils.rest import delete_resources_from_detail

Expand Down Expand Up @@ -43,7 +49,7 @@ def _do_query(**kwargs):

@pytest.mark.ignore_stream("5.10")
@pytest.mark.parametrize("method", ["POST", "DELETE"])
def test_delete_automate_domain_from_detail(appliance, domain_rest, method):
def test_delete_automate_domain_from_detail(domain_rest, method):
"""
Polarion:
assignee: pvala
Expand All @@ -54,11 +60,97 @@ def test_delete_automate_domain_from_detail(appliance, domain_rest, method):


@pytest.mark.ignore_stream("5.10")
def test_delete_automate_domain_from_collection(appliance, domain_rest):
def test_delete_automate_domain_from_collection(domain_rest):
"""
Polarion:
assignee: pvala
casecomponent: Automate
initialEstimate: 1/10h
"""
delete_resources_from_collection([domain_rest], not_found=True, num_sec=50)


@pytest.mark.ignore_stream("5.10")
@pytest.mark.tier(2)
@pytest.mark.meta(
automates=[1486765, 1740340],
blockers=[BZ(1740340, unblock=lambda scheduler: scheduler != "exact_time")],
)
@pytest.mark.parametrize("scheduler", ["number_of_days", "exact_time"])
@test_requirements.rest
def test_schedule_automation_request(appliance, scheduler):
"""
Bugzilla:
1740340
1486765

Polarion:
assignee: pvala
caseimportance: high
casecomponent: Rest
initialEstimate: 1/4h
testSteps:
1. Send a request POST /api/automation_requests
{
"uri_parts" : {
"namespace" : "System",
"class" : "Request",
"instance" : "InspectME",
"message" : "create"
},
"parameters" : {
"var1" : "value 1",
"var2" : "value 2",
"minimum_memory" : 2048,
"schedule_time": scheduler
},
"requester" : {
"auto_approve" : true
}
}
2. Compare the `created_on` and `options::schedule_time` from the response.
expectedResults:
1. Request must be successful.
2.Difference between the two dates must be equal to scheduler
"""
schedule_time = "2" if scheduler == "number_of_days" else "2019-08-14 17:41:06 UTC"
automate_request_rest = appliance.rest_api.collections.automation_requests.action.create(
{
"uri_parts": {
"namespace": "System",
"class": "Request",
"instance": "InspectME",
"message": "create",
},
"parameters": {
"var1": "value 1",
"var2": "value 2",
"minimum_memory": 2048,
"schedule_time": schedule_time,
},
"requester": {"auto_approve": True},
}
)[0]
assert_response(appliance)

automate_request = appliance.collections.automation_requests.instantiate(
description=automate_request_rest.description
)

# This step tests another error that occurred when navigating to the Details page
view = navigate_to(automate_request, "Details")
assert view.is_displayed

def _convert(date):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bit of overkill putting this in a function, could just define date_format as 'constant' and use the same datetime.strptime call using it.

# convert dates to a certain format for easy comparison
date_format = "%m/%d/%y %H:%M"
return datetime.strptime(datetime.strftime(date, date_format), date_format)

scheduled = _convert(parse(automate_request_rest.options["schedule_time"]))

if scheduler == "number_of_days":
created_on = _convert(automate_request_rest.created_on)
difference = scheduled - created_on
assert str(difference.days) == schedule_time
else:
assert _convert(parse(schedule_time)) == scheduled
44 changes: 0 additions & 44 deletions cfme/tests/test_rest_manual.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,47 +86,3 @@ def test_widget_generate_content_via_rest(context):
4. Both values must be different, value must be updated.
"""
pass


@pytest.mark.tier(2)
@pytest.mark.meta(coverage=[1486765, 1740340])
@pytest.mark.parametrize(
"scheduler", ["2", "2019-08-14 17:41:06 UTC"], ids=["number_of_days", "exact_time"]
)
@test_requirements.rest
def test_schedule_automation_request(scheduler):
"""
Bugzilla:
1740340
1486765

Polarion:
assignee: pvala
caseimportance: high
casecomponent: Rest
initialEstimate: 1/4h
testSteps:
1. Send a request POST /api/automation_requests
{
"uri_parts" : {
"namespace" : "System",
"class" : "Request",
"instance" : "InspectME",
"message" : "create"
},
"parameters" : {
"var1" : "value 1",
"var2" : "value 2",
"minimum_memory" : 2048,
"schedule_time": scheduler
},
"requester" : {
"auto_approve" : true
}
}
2. Compare the `created_on` and `options::schedule_time` from the response.
expectedResults:
1. Request must be successful.
2.Difference between the two dates must be equal to scheduler
"""
pass
1 change: 1 addition & 0 deletions entry_points.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ ansible_repositories = cfme.ansible.repositories:RepositoryCollection
ansible_tower_job_templates = cfme.ansible_tower.explorer:AnsibleTowerJobTemplatesCollection
ansible_tower_jobs = cfme.ansible_tower.jobs:TowerJobsCollection
ansible_tower_systems = cfme.infrastructure.config_management.config_systems.ansible_tower:AnsibleTowerSystemsCollection
automation_requests = cfme.automate.requests:AutomationRequestCollection
automate_import_exports = cfme.automate.import_export:AutomateImportExportsCollection
balancers = cfme.networks.balancer:BalancerCollection
block_managers = cfme.storage.manager:BlockManagerCollection
Expand Down