gnocchi/test_{sender,writer): Add some missing tests
A number of unittests were added to cover existing functionality. * gnocchi/test_sender.py * test_send * test_send_error_404 * test_on_authenticated * test_create_request_url * test_handle_http_error * test_handle_http_error_404 * gnocchi/test_writer.py * test_write * test_write_metric_none * test_send_data Change-Id: I81f84c60761667d714a14da9ae8a80fdf59de461
This commit is contained in:
parent
b5cb3b4158
commit
51ad38a2c3
@ -17,6 +17,8 @@
|
||||
|
||||
"""Plugin tests"""
|
||||
|
||||
import mock
|
||||
import requests
|
||||
import unittest
|
||||
|
||||
from collectd_openstack.gnocchi import sender as gnocchi_sender
|
||||
@ -24,5 +26,153 @@ from collectd_openstack.gnocchi import sender as gnocchi_sender
|
||||
|
||||
class TestGnocchiSender(unittest.TestCase):
|
||||
"""Test the sender class."""
|
||||
|
||||
def setUp(self):
|
||||
self.sender = gnocchi_sender.Sender()
|
||||
self.sender._url_base = \
|
||||
"http://my-endpoint/v1/metric/%s/measures"
|
||||
|
||||
def test_init(self):
|
||||
"""Make sure the right things are initialised.
|
||||
|
||||
Set-up: None
|
||||
Test: Create instance of sender
|
||||
Expected behaviour:
|
||||
* sender instance has an empty dict of metric_id mappings
|
||||
"""
|
||||
self.assertEqual(self.sender._meter_ids,
|
||||
{})
|
||||
|
||||
@mock.patch.object(gnocchi_sender.Sender, '_create_request_url')
|
||||
@mock.patch.object(gnocchi_sender.Sender, '_perform_request')
|
||||
def test_send(self, sender_perform_request, sender_create_request_url):
|
||||
"""Test send() in normal circumstances.
|
||||
|
||||
Set-up: Define metername, payload and **kwargs
|
||||
Test: call send with some data
|
||||
Expected behaviour:
|
||||
* _perform_request is called with an unchanged payload
|
||||
* _handle_http_error is not called
|
||||
"""
|
||||
self.sender._auth_token = "my-auth-token"
|
||||
|
||||
sender_create_request_url.return_value = \
|
||||
"http://my-endpoint/v1/metric/my-metrid-id/measures"
|
||||
|
||||
expected_args = (
|
||||
"http://my-endpoint/v1/metric/my-metrid-id/measures",
|
||||
"some-payload",
|
||||
"my-auth-token")
|
||||
|
||||
self.sender.send("my-metername", "some-payload", unit="some-unit")
|
||||
sender_perform_request.assert_called_with(*expected_args)
|
||||
|
||||
@mock.patch.object(gnocchi_sender.Sender, '_handle_http_error')
|
||||
@mock.patch('requests.post')
|
||||
@mock.patch.object(gnocchi_sender.Sender, '_create_request_url')
|
||||
@mock.patch.object(gnocchi_sender.Sender, '_authenticate')
|
||||
def test_send_error_404(self, sender_authenticate,
|
||||
sender_create_request_url,
|
||||
post,
|
||||
sender_handle_http_err):
|
||||
"""Test send when metric is not defined
|
||||
|
||||
Tests what happens when metric is not defined i.e. 404 is returned
|
||||
|
||||
Set-up:
|
||||
Test: post returns a 404 when attenpting to create a measure
|
||||
Expected behaviour:
|
||||
* _handle_http_request is called to handle the 404
|
||||
"""
|
||||
response_not_found = requests.Response()
|
||||
response_not_found.status_code = 404
|
||||
exc = requests.exceptions.HTTPError(
|
||||
u'404 Client Error: None for url: None',
|
||||
response=response_not_found)
|
||||
|
||||
# send() mock the steps moving up to _perform_request
|
||||
sender_authenticate.return_value = "my_auth_token"
|
||||
sender_create_request_url.return_value = "http://my-request-url"
|
||||
# When the request is made, it fails
|
||||
post.return_value = exc.response
|
||||
|
||||
self.sender.send("my-meter", "payload", resource_id="my-resource")
|
||||
sender_handle_http_err.assert_called()
|
||||
|
||||
@mock.patch.object(gnocchi_sender.Sender, '_get_endpoint')
|
||||
def test_on_authenticated(self, sender_get_endpoint):
|
||||
"""Test sender._on_authenticated
|
||||
|
||||
Set-up: None
|
||||
Test: Call sender._on_authenticated
|
||||
Expected behaviour: sender._url_base is set correctly
|
||||
"""
|
||||
expected_url = \
|
||||
"http://my-endpoint/v1/metric/%s/measures"
|
||||
|
||||
sender_get_endpoint.return_value = "http://my-endpoint"
|
||||
|
||||
self.sender._on_authenticated()
|
||||
|
||||
self.assertEqual(self.sender._url_base,
|
||||
expected_url)
|
||||
|
||||
@mock.patch.object(gnocchi_sender.Sender, '_get_metric_id')
|
||||
@mock.patch.object(gnocchi_sender.Sender, '_get_endpoint')
|
||||
def test_create_request_url(self, sender_get_endpoint,
|
||||
sender_get_metric_id):
|
||||
"""Test create_request_url
|
||||
|
||||
Set-up: None
|
||||
Test: call _create_requet_url
|
||||
Expected behaviour: sender_url_base is is returned
|
||||
"""
|
||||
expected_url = \
|
||||
"http://my-endpoint/v1/metric/my-metric-name/measures"
|
||||
|
||||
sender_get_endpoint.return_value = "http://my-endpoint"
|
||||
sender_get_metric_id.return_value = "my-metric-name"
|
||||
|
||||
url = self.sender._create_request_url("my-metric-name", unit="my-unit")
|
||||
self.assertEqual(url,
|
||||
expected_url)
|
||||
|
||||
def test_handle_http_error(self):
|
||||
"""Tesing the response to a HTTPError that is not a 404.
|
||||
|
||||
Set-up: Create an Exception to use as a parameter
|
||||
Test: Use exception as an input parameter
|
||||
Expected behaviour: exception is raised again
|
||||
"""
|
||||
res = requests.Response()
|
||||
res.status_code = 402
|
||||
exc = requests.HTTPError("Oh no! there was an error!",
|
||||
response=res)
|
||||
|
||||
self.assertRaises(requests.exceptions.HTTPError,
|
||||
self.sender._handle_http_error,
|
||||
exc, "my-meter", "some-payload", "my-auth-token")
|
||||
|
||||
@mock.patch.object(gnocchi_sender.Sender, '_get_metric_id')
|
||||
@mock.patch.object(gnocchi_sender.Sender, '_perform_request', autospec=True)
|
||||
def test_handle_http_error_404(self, sender_perf_req,
|
||||
sender_get_metric_id):
|
||||
"""Test response to a HTTP 404 Error
|
||||
|
||||
Set-up: Create the HTTPError
|
||||
Test: Call _handle_http_error with appropriate inputs
|
||||
Expected behaviour:
|
||||
* Sender will try to create_or_update_resource
|
||||
"""
|
||||
res = requests.Response()
|
||||
res.status_code = 404
|
||||
exc = requests.exceptions.HTTPError("Oh no! It wasn't found!",
|
||||
response=res)
|
||||
success = requests.Response()
|
||||
success.status_code = 201
|
||||
sender_perf_req.return_value = success
|
||||
sender_get_metric_id.return_value = "my-metric-name"
|
||||
|
||||
self.sender._handle_http_error(exc, "my-meter", "some-payload",
|
||||
"my-auth-token", unit="my-unit",
|
||||
resource_id="my-resource-id")
|
||||
|
@ -16,10 +16,13 @@
|
||||
# under the License.
|
||||
"""Gnocchi Writer tests"""
|
||||
|
||||
import json
|
||||
import mock
|
||||
import requests
|
||||
import unittest
|
||||
|
||||
from collectd_openstack.common.meters import MeterStorage
|
||||
from collectd_openstack.gnocchi import sender as gnocchi_sender
|
||||
from collectd_openstack.gnocchi import writer
|
||||
|
||||
|
||||
@ -110,3 +113,112 @@ class TestGnocchiWriter(unittest.TestCase):
|
||||
|
||||
meters = MeterStorage(collectd=collectd)
|
||||
self.writer = writer.Writer(meters=meters, config=config)
|
||||
self.writer._sender._auth_token = "my_auth_token"
|
||||
|
||||
@mock.patch.object(gnocchi_sender.Sender, '_create_request_url')
|
||||
@mock.patch.object(gnocchi_sender.Sender, '_get_endpoint')
|
||||
@mock.patch.object(gnocchi_sender.Sender, '_authenticate')
|
||||
@mock.patch('requests.post', autospec=True)
|
||||
@mock_value()
|
||||
def test_write(self, vl, post, sender_authenticate, sender_get_endpoint,
|
||||
sender_create_request_url):
|
||||
"""Test write with successful results
|
||||
|
||||
Set-up: None
|
||||
Test: call write with expected data
|
||||
Expected behaviour:
|
||||
* POST is called successfully
|
||||
* No error occurs i.e. no error is raised
|
||||
"""
|
||||
response_ok = requests.Response()
|
||||
response_ok.status_code = 200
|
||||
post.return_value = response_ok
|
||||
|
||||
self.writer._sender._url_base = "my-url"
|
||||
sender_get_endpoint.return_value = "http://my-endpoint"
|
||||
sender_create_request_url.return_value = \
|
||||
"http://my-endpoint/v1/metrics/my-metric-id/measures"
|
||||
sender_authenticate.return_value = "auth_token"
|
||||
# Force the url to be updated without actually authenticating
|
||||
self.writer._sender._on_authenticated()
|
||||
|
||||
expected_url = "http://my-endpoint/v1/metrics/my-metric-id/measures"
|
||||
expected_payload = json.dumps([
|
||||
{
|
||||
"value": 1234,
|
||||
"timestamp": "1973-11-29T21:33:09"
|
||||
},
|
||||
])
|
||||
|
||||
expected_kwargs = {"data": expected_payload,
|
||||
"headers": mock.ANY,
|
||||
"timeout": mock.ANY}
|
||||
|
||||
self.writer.write(vl, None)
|
||||
post.assert_called_with(expected_url, **expected_kwargs)
|
||||
|
||||
@mock.patch.object(gnocchi_sender.Sender, '_get_endpoint')
|
||||
@mock.patch.object(gnocchi_sender.Sender, '_authenticate')
|
||||
@mock.patch.object(gnocchi_sender.Sender, '_create_metric')
|
||||
@mock.patch('requests.post', autospec=True)
|
||||
@mock_value()
|
||||
def test_write_metric_none(self, vl, post,
|
||||
sender_create_metric,
|
||||
sender_authenticate,
|
||||
sender_get_endpoint):
|
||||
"""Test Writer.write() when there is no meter defined.
|
||||
|
||||
Set-up:
|
||||
Test: Sender throws a HTTPError with status=404
|
||||
Expected behaviour:
|
||||
* _create_or_update_resource is called with appropriate args
|
||||
"""
|
||||
|
||||
response_not_found = requests.Response()
|
||||
response_not_found.status_code = 404
|
||||
|
||||
response_ok = requests.Response()
|
||||
response_ok.status_code = 200
|
||||
|
||||
# post will be called to submit sample before AND after handling
|
||||
# the error
|
||||
post.side_effect = [response_not_found, response_ok]
|
||||
|
||||
self.writer._sender._url_base = "my-url"
|
||||
sender_get_endpoint.return_value = "http://my-endpoint"
|
||||
sender_authenticate.return_value = "auth_token"
|
||||
|
||||
self.writer.write(vl, data=None)
|
||||
|
||||
sender_create_metric.assert_called()
|
||||
|
||||
@mock.patch.object(gnocchi_sender.Sender, 'send')
|
||||
@mock_value()
|
||||
def test_send_data(self, vl, sender_send):
|
||||
"""Test _send_data() to make sure the correct payoad is being sent.
|
||||
|
||||
Set-up: Create a sample
|
||||
Test: call _send_data
|
||||
Expected behaviour:
|
||||
* Sender.send() is called with the correct payload and args
|
||||
"""
|
||||
sample = writer.Sample(value=42, timestamp=0, meta=None,
|
||||
unit="my-unit", metername="my-metername")
|
||||
# TODO(emma-l-foley): Add docstring to _send_data specifying the inputs.
|
||||
# to_send should be a list of Sample objects
|
||||
to_send = [sample]
|
||||
|
||||
expected_payload = json.dumps([
|
||||
{
|
||||
"value": 42,
|
||||
"timestamp": 0
|
||||
}
|
||||
])
|
||||
|
||||
expected_args = ("my-metername", expected_payload)
|
||||
expected_kwargs = {"unit": "my-unit"}
|
||||
|
||||
self.writer._send_data("my-metername", to_send,
|
||||
unit="my-unit",)
|
||||
|
||||
sender_send.assert_called_with(*expected_args, **expected_kwargs)
|
||||
|
Loading…
x
Reference in New Issue
Block a user