blob: 0d2f8b8af714b752d99bf441385adae2d4d26361 [file] [log] [blame]
# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import json
import os
import unittest
import httplib2
import mock
from infra_libs import httplib2_utils
from infra_libs.ts_mon.common import interface
from infra_libs.ts_mon.common import monitors
from infra_libs.ts_mon.common import pb_to_popo
from infra_libs.ts_mon.protos import metrics_pb2
import infra_libs
class MonitorTest(unittest.TestCase):
def test_send(self):
m = monitors.Monitor()
metric1 = metrics_pb2.MetricsPayload()
with self.assertRaises(NotImplementedError):
m.send(metric1)
class HttpsMonitorTest(unittest.TestCase):
def setUp(self):
interface.state.reset_for_unittest()
def message(self, pb):
return json.dumps({'payload': pb_to_popo.convert(pb)})
def _test_send(self, http):
mon = monitors.HttpsMonitor('endpoint',
monitors.CredentialFactory.from_string(':gce'), http=http)
resp = mock.MagicMock(spec=httplib2.Response, status=200)
mon._http.request = mock.MagicMock(return_value=[resp, ""])
payload = metrics_pb2.MetricsPayload()
payload.metrics_collection.add().metrics_data_set.add().metric_name = 'a'
mon.send(payload)
mon._http.request.assert_has_calls([
mock.call('endpoint', method='POST', body=self.message(payload),
headers={'Content-Type': 'application/json'}),
])
def test_default_send(self):
self._test_send(None)
def test_http_send(self):
self._test_send(httplib2.Http())
def test_instrumented_http_send(self):
self._test_send(httplib2_utils.InstrumentedHttp('test'))
@mock.patch('infra_libs.ts_mon.common.monitors.CredentialFactory.'
'from_string')
def test_send_resp_failure(self, _load_creds):
mon = monitors.HttpsMonitor('endpoint',
monitors.CredentialFactory.from_string('/path/to/creds.p8.json'))
resp = mock.MagicMock(spec=httplib2.Response, status=400)
mon._http.request = mock.MagicMock(return_value=[resp, ""])
metric1 = metrics_pb2.MetricsPayload()
metric1.metrics_collection.add().metrics_data_set.add().metric_name = 'a'
mon.send(metric1)
mon._http.request.assert_called_once_with(
'endpoint',
method='POST',
body=self.message(metric1),
headers={'Content-Type': 'application/json'})
@mock.patch('infra_libs.ts_mon.common.monitors.CredentialFactory.'
'from_string')
def test_send_http_failure(self, _load_creds):
mon = monitors.HttpsMonitor('endpoint',
monitors.CredentialFactory.from_string('/path/to/creds.p8.json'))
mon._http.request = mock.MagicMock(side_effect=ValueError())
metric1 = metrics_pb2.MetricsPayload()
metric1.metrics_collection.add().metrics_data_set.add().metric_name = 'a'
mon.send(metric1)
mon._http.request.assert_called_once_with(
'endpoint',
method='POST',
body=self.message(metric1),
headers={'Content-Type': 'application/json'})
class DebugMonitorTest(unittest.TestCase):
def test_send_file(self):
with infra_libs.temporary_directory() as temp_dir:
filename = os.path.join(temp_dir, 'out')
m = monitors.DebugMonitor(filename)
payload = metrics_pb2.MetricsPayload()
payload.metrics_collection.add().metrics_data_set.add().metric_name = 'm1'
m.send(payload)
with open(filename) as fh:
output = fh.read()
self.assertIn('metrics_data_set {\n metric_name: "m1"\n }', output)
@mock.patch('logging.info')
def test_send_log(self, mock_logging_info):
m = monitors.DebugMonitor()
payload = metrics_pb2.MetricsPayload()
payload.metrics_collection.add().metrics_data_set.add().metric_name = 'm1'
m.send(payload)
self.assertEqual(1, mock_logging_info.call_count)
output = mock_logging_info.call_args[0][1]
self.assertIn('metrics_data_set {\n metric_name: "m1"\n }', output)
class NullMonitorTest(unittest.TestCase):
def test_send(self):
m = monitors.NullMonitor()
payload = metrics_pb2.MetricsPayload()
payload.metrics_collection.add().metrics_data_set.add().metric_name = 'm1'
m.send(payload)
class CredentialFactoryTest(unittest.TestCase):
def test_from_string(self):
self.assertIsInstance(monitors.CredentialFactory.from_string(':gce'),
monitors.GCECredentials)
self.assertIsInstance(monitors.CredentialFactory.from_string(':appengine'),
monitors.AppengineCredentials)
self.assertIsInstance(monitors.CredentialFactory.from_string('/foo'),
monitors.FileCredentials)
@mock.patch('infra_libs.httplib2_utils.DelegateServiceAccountCredentials',
autospec=True)
def test_actor_credentials(self, mock_creds):
base = mock.Mock(monitors.CredentialFactory)
c = monitors.DelegateServiceAccountCredentials('test@example.com', base)
creds = c.create(['foo'])
base.create.assert_called_once_with(['https://www.googleapis.com/auth/iam'])
base.create.return_value.authorize.assert_called_once_with(mock.ANY)
mock_creds.assert_called_once_with(
base.create.return_value.authorize.return_value,
'test@example.com', ['foo'])
self.assertEqual(mock_creds.return_value, creds)
@mock.patch('oauth2client.client.GoogleCredentials.from_stream')
def test_file_credentials_google(self, mock_from_stream):
with infra_libs.temporary_directory() as temp_dir:
path = os.path.join(temp_dir, 'foo')
with open(path, 'w') as fh:
json.dump({'type': 'blah'}, fh)
ret = monitors.FileCredentials(path).create(['bar'])
mock_from_stream.assert_called_once_with(path)
creds = mock_from_stream.return_value
creds.create_scoped.assert_called_once_with(['bar'])
self.assertEqual(ret, creds.create_scoped.return_value)
@mock.patch('infra_libs.ts_mon.common.monitors.Storage')
def test_file_credentials_non_google(self, mock_storage):
with infra_libs.temporary_directory() as temp_dir:
path = os.path.join(temp_dir, 'foo')
with open(path, 'w') as fh:
json.dump({}, fh)
ret = monitors.FileCredentials(path).create(['bar'])
mock_storage.assert_called_once_with(path)
mock_storage.return_value.get.assert_called_once_with()
self.assertEqual(ret, mock_storage.return_value.get.return_value)