Skip to content
This repository has been archived by the owner on Sep 26, 2019. It is now read-only.

Commit

Permalink
Merge "API tests for analytics endpoint."
Browse files Browse the repository at this point in the history
  • Loading branch information
Jenkins authored and openstack-gerrit committed May 17, 2016
2 parents 58127ee + 3b0cc11 commit 4d95781
Show file tree
Hide file tree
Showing 4 changed files with 316 additions and 3 deletions.
153 changes: 153 additions & 0 deletions tests/api/services/test_analytics.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
# coding= utf-8

# Copyright (c) 2014 Rackspace, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import datetime
import uuid

import ddt
import hypothesis
from hypothesis.extra import datetime as hypothesis_datetime
from hypothesis import strategies

from tests.api import base
from tests.api.utils.schema import analytics


@ddt.ddt
class TestAnalytics(base.TestBase):

"""Tests for Analytics."""

def setUp(self):
super(TestAnalytics, self).setUp()

self.flavor_id = self.test_flavor
service_name = str(uuid.uuid1())

self.domain = self.generate_random_string(
prefix='www.api-test-domain') + '.com'
self.domain_list = [{"domain": self.domain}]

self.origin_list = [{"origin": self.generate_random_string(
prefix='api-test-origin') + '.com', "port": 80, "ssl": False,
"hostheadertype": "custom", "hostheadervalue":
"www.customweb.com"}]

self.caching_list = [{"name": "default", "ttl": 3600},
{"name": "home", "ttl": 1200,
"rules": [{"name": "index",
"request_url": "/index.htm"}]}]
self.log_delivery = {"enabled": False}

resp = self.client.create_service(service_name=service_name,
domain_list=self.domain_list,
origin_list=self.origin_list,
caching_list=self.caching_list,
flavor_id=self.flavor_id,
log_delivery=self.log_delivery)

self.location = resp.headers["location"]
self.client.wait_for_service_status(
location=self.location,
status='deployed',
abort_on_status='failed',
retry_interval=self.test_config.status_check_retry_interval,
retry_timeout=self.test_config.status_check_retry_timeout)

@ddt.data('requestCount', 'bandwidthOut', 'httpResponseCode_2XX',
'httpResponseCode_3XX', 'httpResponseCode_4XX',
'httpResponseCode_5XX')
def test_analytics(self, metric_type):
end_time = datetime.datetime.now()
delta_days = datetime.timedelta(days=1)
start_time = end_time - delta_days

start_time_str = start_time.strftime('%Y-%m-%dT%H:%M:%S')
end_time_str = end_time.strftime('%Y-%m-%dT%H:%M:%S')
domain = self.domain

resp = self.client.get_analytics(
location=self.location, domain=domain, start_time=start_time_str,
end_time=end_time_str, metric_type=metric_type)
self.assertEqual(resp.status_code, 200)

body = resp.json()
if metric_type == 'requestCount':
self.assertSchema(body, analytics.get_request_count)
elif metric_type == 'bandwidthOut':
self.assertSchema(body, analytics.get_bandwidthOut)
elif metric_type == 'httpResponseCode_2XX':
self.assertSchema(body, analytics.get_httpResponseCode_2XX)
elif metric_type == 'httpResponseCode_3XX':
self.assertSchema(body, analytics.get_httpResponseCode_3XX)
elif metric_type == 'httpResponseCode_4XX':
self.assertSchema(body, analytics.get_httpResponseCode_4XX)
elif metric_type == 'httpResponseCode_5XX':
self.assertSchema(body, analytics.get_httpResponseCode_5XX)

@hypothesis.given(strategies.text())
def test_analytics_negative_metric_type(self, metric_type):
end_time = datetime.datetime.now()
delta_days = datetime.timedelta(days=1)
start_time = end_time - delta_days

start_time_str = start_time.strftime('%Y-%m-%dT%H:%M:%S')
end_time_str = end_time.strftime('%Y-%m-%dT%H:%M:%S')
domain = self.domain

resp = self.client.get_analytics(
location=self.location, domain=domain, start_time=start_time_str,
end_time=end_time_str, metric_type=metric_type)
self.assertEqual(resp.status_code, 400)

@hypothesis.given(strategies.text())
def test_analytics_negative_domain(self, domain):
end_time = datetime.datetime.now()
delta_days = datetime.timedelta(days=1)
start_time = end_time - delta_days

start_time_str = start_time.strftime('%Y-%m-%dT%H:%M:%S')
end_time_str = end_time.strftime('%Y-%m-%dT%H:%M:%S')
metric_type = 'httpResponseCode_2XX'

resp = self.client.get_analytics(
location=self.location, domain=domain, start_time=start_time_str,
end_time=end_time_str, metric_type=metric_type)
self.assertEqual(resp.status_code, 400)

# the datetime strftime() methods requires year >= 1900
@hypothesis.given(hypothesis_datetime.datetimes(min_year=1900),
hypothesis_datetime.datetimes(min_year=1900))
def test_analytics_negative_time_range(self, start_time, end_time):
start_time_str = start_time.strftime('%Y-%m-%dT%H:%M:%S')
end_time_str = end_time.strftime('%Y-%m-%dT%H:%M:%S')
metric_type = 'requestCount'
domain = self.domain

resp = self.client.get_analytics(
location=self.location, domain=domain, start_time=start_time_str,
end_time=end_time_str, metric_type=metric_type)
# Verify that we never get back a HTTP 500
self.assertIn(resp.status_code, [200, 400])

def tearDown(self):
self.client.delete_service(location=self.location)

if self.test_config.generate_flavors:
self.client.delete_flavor(flavor_id=self.flavor_id)

super(TestAnalytics, self).tearDown()
24 changes: 22 additions & 2 deletions tests/api/utils/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,7 @@ def list_services(self, param=None,
return self.request('GET', url, params=param,
requestslib_kwargs=requestslib_kwargs)

def delete_service(self, location,
requestslib_kwargs=None):
def delete_service(self, location, requestslib_kwargs=None):
"""Delete Service
:return: Response Object containing response code 204
Expand All @@ -211,6 +210,27 @@ def delete_service(self, location,
return self.request('DELETE', location,
requestslib_kwargs=requestslib_kwargs)

def get_analytics(self, location, domain, start_time, metric_type,
end_time=None, requestslib_kwargs=None):
"""Get Analytics for the domain
:return: Response Object containing response code 200
GET
location/analytics?domain=domain&startTime=startTime&endTime=endTime
&metricType=metricType
"""
if end_time:
url = location + \
u'/analytics?domain={0}&startTime={1}&endTime={2}\
&metricType={3}'.format(
domain, start_time, end_time, metric_type)
else:
url = location + \
u'/analytics?domain={0}&startTime={1}&metricType={3}'.format(
domain, start_time, metric_type)

return self.request('GET', url, requestslib_kwargs=requestslib_kwargs)

def admin_get_service_by_domain_name(self, domain):
"""Get Service By domain name
Expand Down
140 changes: 140 additions & 0 deletions tests/api/utils/schema/analytics.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
# Copyright (c) 2016 Rackspace, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.

get_request_count = {
'type': 'object',
'properties': {
'domain': {'type': 'string', 'format': 'uri'},
'requestCount':
{'type': 'object',
'properties': {
'India': {'type': 'array', 'items': {'type': 'array'}},
'EMEA': {'type': 'array', 'items': {'type': 'array'}},
'APAC': {'type': 'array', 'items': {'type': 'array'}},
'North America': {
'type': 'array', 'items': {'type': 'array'}},
'South America': {
'type': 'array', 'items': {'type': 'array'}},
'Japan': {'type': 'array', 'items': {'type': 'array'}},
}},
'flavor': {'type': 'string', 'enum': ['cdn']},
'provider': {'type': 'string', 'enum': ['akamai']},
}
}

get_bandwidthOut = {
'type': 'object',
'properties': {
'domain': {'type': 'string', 'format': 'uri'},
'bandwidthOut':
{'type': 'object',
'properties': {
'India': {'type': 'array', 'items': {'type': 'array'}},
'EMEA': {'type': 'array', 'items': {'type': 'array'}},
'APAC': {'type': 'array', 'items': {'type': 'array'}},
'North America': {
'type': 'array', 'items': {'type': 'array'}},
'South America': {
'type': 'array', 'items': {'type': 'array'}},
'Japan': {'type': 'array', 'items': {'type': 'array'}},
}},
'flavor': {'type': 'string', 'enum': ['cdn']},
'provider': {'type': 'string', 'enum': ['akamai']},
}
}

get_httpResponseCode_2XX = {
'type': 'object',
'properties': {
'domain': {'type': 'string', 'format': 'uri'},
'httpResponseCode_2XX':
{'type': 'object',
'properties': {
'India': {'type': 'array', 'items': {'type': 'array'}},
'EMEA': {'type': 'array', 'items': {'type': 'array'}},
'APAC': {'type': 'array', 'items': {'type': 'array'}},
'North America': {
'type': 'array', 'items': {'type': 'array'}},
'South America': {
'type': 'array', 'items': {'type': 'array'}},
'Japan': {'type': 'array', 'items': {'type': 'array'}},
}},
'flavor': {'type': 'string', 'enum': ['cdn']},
'provider': {'type': 'string', 'enum': ['akamai']},
}
}

get_httpResponseCode_3XX = {
'type': 'object',
'properties': {
'domain': {'type': 'string', 'format': 'uri'},
'httpResponseCode_3XX':
{'type': 'object',
'properties': {
'India': {'type': 'array', 'items': {'type': 'array'}},
'EMEA': {'type': 'array', 'items': {'type': 'array'}},
'APAC': {'type': 'array', 'items': {'type': 'array'}},
'North America': {
'type': 'array', 'items': {'type': 'array'}},
'South America': {
'type': 'array', 'items': {'type': 'array'}},
'Japan': {'type': 'array', 'items': {'type': 'array'}},
}},
'flavor': {'type': 'string', 'enum': ['cdn']},
'provider': {'type': 'string', 'enum': ['akamai']},
}
}

get_httpResponseCode_4XX = {
'type': 'object',
'properties': {
'domain': {'type': 'string', 'format': 'uri'},
'httpResponseCode_4XX':
{'type': 'object',
'properties': {
'India': {'type': 'array', 'items': {'type': 'array'}},
'EMEA': {'type': 'array', 'items': {'type': 'array'}},
'APAC': {'type': 'array', 'items': {'type': 'array'}},
'North America': {
'type': 'array', 'items': {'type': 'array'}},
'South America': {
'type': 'array', 'items': {'type': 'array'}},
'Japan': {'type': 'array', 'items': {'type': 'array'}},
}},
'flavor': {'type': 'string', 'enum': ['cdn']},
'provider': {'type': 'string', 'enum': ['akamai']},
}
}

get_httpResponseCode_5XX = {
'type': 'object',
'properties': {
'domain': {'type': 'string', 'format': 'uri'},
'httpResponseCode_5XX':
{'type': 'object',
'properties': {
'India': {'type': 'array', 'items': {'type': 'array'}},
'EMEA': {'type': 'array', 'items': {'type': 'array'}},
'APAC': {'type': 'array', 'items': {'type': 'array'}},
'North America': {
'type': 'array', 'items': {'type': 'array'}},
'South America': {
'type': 'array', 'items': {'type': 'array'}},
'Japan': {'type': 'array', 'items': {'type': 'array'}},
}},
'flavor': {'type': 'string', 'enum': ['cdn']},
'provider': {'type': 'string', 'enum': ['akamai']},
}
}
2 changes: 1 addition & 1 deletion tests/test-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ requests-mock
testrepository
testtools
beautifulsoup4
hypothesis
hypothesis

0 comments on commit 4d95781

Please sign in to comment.