Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(490)

Unified Diff: third_party/google-endpoints/test/test_client.py

Issue 2666783008: Add google-endpoints to third_party/. (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/google-endpoints/test/test_client.py
diff --git a/third_party/google-endpoints/test/test_client.py b/third_party/google-endpoints/test/test_client.py
new file mode 100644
index 0000000000000000000000000000000000000000..1678fa3ff3bc23a50aa6d6ee4759228e0a0fa782
--- /dev/null
+++ b/third_party/google-endpoints/test/test_client.py
@@ -0,0 +1,431 @@
+# Copyright 2016 Google Inc. All Rights Reserved.
+#
+# 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.
+
+from __future__ import absolute_import
+
+import datetime
+import mock
+import os
+import tempfile
+import unittest2
+from expects import be_false, be_none, be_true, expect, equal, raise_error
+
+from google.api.control import caches, check_request, client, messages, report_request
+
+
+class TestSimpleLoader(unittest2.TestCase):
+ SERVICE_NAME = 'simpler-loader'
+
+ @mock.patch("google.api.control.client.ReportOptions", autospec=True)
+ @mock.patch("google.api.control.client.CheckOptions", autospec=True)
+ def test_should_create_client_ok(self, check_opts, report_opts):
+ # the mocks return fake instances else code using them fails
+ check_opts.return_value = caches.CheckOptions()
+ report_opts.return_value = caches.ReportOptions()
+
+ # ensure the client is constructed using no args instances of the opts
+ expect(client.Loaders.DEFAULT.load(self.SERVICE_NAME)).not_to(be_none)
+ check_opts.assert_called_once_with()
+ report_opts.assert_called_once_with()
+
+_TEST_CONFIG = """{
+ "checkAggregatorConfig": {
+ "cacheEntries": 10,
+ "responseExpirationMs": 1000,
+ "flushIntervalMs": 2000
+ },
+ "reportAggregatorConfig": {
+ "cacheEntries": 10,
+ "flushIntervalMs": 1000
+ }
+}
+"""
+
+
+class TestEnvironmentLoader(unittest2.TestCase):
+ SERVICE_NAME = 'environment-loader'
+
+ def setUp(self):
+ json_fd = tempfile.NamedTemporaryFile(delete=False)
+ with json_fd as f:
+ f.write(_TEST_CONFIG)
+ self._config_file = json_fd.name
+ os.environ[client.CONFIG_VAR] = self._config_file
+
+ def tearDown(self):
+ if os.path.exists(self._config_file):
+ os.remove(self._config_file)
+
+ @mock.patch("google.api.control.client.ReportOptions", autospec=True)
+ @mock.patch("google.api.control.client.CheckOptions", autospec=True)
+ def test_should_create_client_from_environment_ok(self, check_opts, report_opts):
+ check_opts.return_value = caches.CheckOptions()
+ report_opts.return_value = caches.ReportOptions()
+
+ # ensure the client is constructed using options values from the test JSON
+ expect(client.Loaders.ENVIRONMENT.load(self.SERVICE_NAME)).not_to(be_none)
+ check_opts.assert_called_once_with(expiration=datetime.timedelta(0, 1),
+ flush_interval=datetime.timedelta(0, 2),
+ num_entries=10)
+ report_opts.assert_called_once_with(flush_interval=datetime.timedelta(0, 1),
+ num_entries=10)
+
+ @mock.patch("google.api.control.client.ReportOptions", autospec=True)
+ @mock.patch("google.api.control.client.CheckOptions", autospec=True)
+ def test_should_use_defaults_if_file_is_missing(self, check_opts, report_opts):
+ os.remove(self._config_file)
+ self._assert_called_with_no_args_options(check_opts, report_opts)
+
+ @mock.patch("google.api.control.client.ReportOptions", autospec=True)
+ @mock.patch("google.api.control.client.CheckOptions", autospec=True)
+ def test_should_use_defaults_if_file_is_missing(self, check_opts, report_opts):
+ del os.environ[client.CONFIG_VAR]
+ self._assert_called_with_no_args_options(check_opts, report_opts)
+
+ @mock.patch("google.api.control.client.ReportOptions")
+ @mock.patch("google.api.control.client.CheckOptions")
+ def test_should_use_defaults_if_json_is_bad(self, check_opts, report_opts):
+ with open(self._config_file, 'w') as f:
+ f.write(_TEST_CONFIG + '\n{ this will not parse as json}')
+ self._assert_called_with_no_args_options(check_opts, report_opts)
+
+ def _assert_called_with_no_args_options(self, check_opts, report_opts):
+ # the mocks return fake instances else code using them fails
+ check_opts.return_value = caches.CheckOptions()
+ report_opts.return_value = caches.ReportOptions()
+
+ # ensure the client is constructed using no args instances of the opts
+ expect(client.Loaders.ENVIRONMENT.load(self.SERVICE_NAME)).not_to(be_none)
+ check_opts.assert_called_once_with()
+ report_opts.assert_called_once_with()
+
+
+def _make_dummy_report_request(project_id, service_name):
+ rules = report_request.ReportingRules()
+ info = report_request.Info(
+ consumer_project_id=project_id,
+ operation_id='an_op_id',
+ operation_name='an_op_name',
+ method='GET',
+ referer='a_referer',
+ service_name=service_name)
+ return info.as_report_request(rules)
+
+
+def _make_dummy_check_request(project_id, service_name):
+ info = check_request.Info(
+ consumer_project_id=project_id,
+ operation_id='an_op_id',
+ operation_name='an_op_name',
+ referer='a_referer',
+ service_name=service_name)
+ return info.as_check_request()
+
+
+class TestClientStartAndStop(unittest2.TestCase):
+ SERVICE_NAME = 'start-and-stop'
+ PROJECT_ID = SERVICE_NAME + '.project'
+
+ def setUp(self):
+ self._mock_transport = mock.MagicMock()
+ self._subject = client.Loaders.DEFAULT.load(
+ self.SERVICE_NAME,
+ create_transport=lambda: self._mock_transport)
+
+ @mock.patch("google.api.control.client._THREAD_CLASS", spec=True)
+ def test_should_create_a_thread_when_started(self, thread_class):
+ self._subject.start()
+ expect(thread_class.called).to(be_true)
+ expect(len(thread_class.call_args_list)).to(equal(1))
+
+ @mock.patch("google.api.control.client._THREAD_CLASS", spec=True)
+ def test_should_only_create_thread_on_first_start(self, thread_class):
+ self._subject.start()
+ self._subject.start()
+ expect(len(thread_class.call_args_list)).to(equal(1))
+
+ def test_should_noop_stop_if_not_started(self):
+ # stop the subject, the transport should not see a request
+ self._subject.stop()
+ expect(self._mock_transport.called).to(be_false)
+
+ @mock.patch("google.api.control.client._THREAD_CLASS", spec=True)
+ def test_should_clear_requests_on_stop(self, dummy_thread_class):
+ # stop the subject, the transport did not see a request
+ self._subject.start()
+ self._subject.report(
+ _make_dummy_report_request(self.PROJECT_ID, self.SERVICE_NAME))
+ self._subject.stop()
+ expect(self._mock_transport.services.report.called).to(be_true)
+
+ @mock.patch("google.api.control.client._THREAD_CLASS", spec=True)
+ def test_should_ignore_stop_if_already_stopped(self, dummy_thread_class):
+ # stop the subject, the transport did not see a request
+ self._subject.start()
+ self._subject.report(
+ _make_dummy_report_request(self.PROJECT_ID, self.SERVICE_NAME))
+ self._subject.stop()
+ self._mock_transport.reset_mock()
+ self._subject.stop()
+ expect(self._mock_transport.services.report.called).to(be_false)
+
+ @mock.patch("google.api.control.client._THREAD_CLASS", spec=True)
+ def test_should_ignore_bad_transport_when_not_cached(self, dummy_thread_class):
+ self._subject.start()
+ self._subject.report(
+ _make_dummy_report_request(self.PROJECT_ID, self.SERVICE_NAME))
+ self._mock_transport.services.report.side_effect = lambda: 1/0
+ self._subject.stop()
+ expect(self._mock_transport.services.report.called).to(be_true)
+
+
+class TestClientCheck(unittest2.TestCase):
+ SERVICE_NAME = 'check'
+ PROJECT_ID = SERVICE_NAME + '.project'
+
+ def setUp(self):
+ self._mock_transport = mock.MagicMock()
+ self._subject = client.Loaders.DEFAULT.load(
+ self.SERVICE_NAME,
+ create_transport=lambda: self._mock_transport)
+
+ def test_should_raise_on_check_without_start(self):
+ dummy_request = _make_dummy_check_request(self.PROJECT_ID,
+ self.SERVICE_NAME)
+ expect(lambda: self._subject.check(dummy_request)).to(
+ raise_error(AssertionError))
+
+ @mock.patch("google.api.control.client._THREAD_CLASS", spec=True)
+ def test_should_send_the_request_if_not_cached(self, dummy_thread_class):
+ self._subject.start()
+ dummy_request = _make_dummy_check_request(self.PROJECT_ID,
+ self.SERVICE_NAME)
+ self._subject.check(dummy_request)
+ expect(self._mock_transport.services.check.called).to(be_true)
+
+ @mock.patch("google.api.control.client._THREAD_CLASS", spec=True)
+ def test_should_not_send_the_request_if_cached(self, dummy_thread_class):
+ t = self._mock_transport
+ self._subject.start()
+ dummy_request = _make_dummy_check_request(self.PROJECT_ID,
+ self.SERVICE_NAME)
+ dummy_response = messages.CheckResponse(
+ operationId=dummy_request.checkRequest.operation.operationId)
+ t.services.check.return_value = dummy_response
+ expect(self._subject.check(dummy_request)).to(equal(dummy_response))
+ t.reset_mock()
+ expect(self._subject.check(dummy_request)).to(equal(dummy_response))
+ expect(t.services.check.called).to(be_false)
+
+ @mock.patch("google.api.control.client._THREAD_CLASS", spec=True)
+ def test_should_return_null_if_transport_fails(self, dummy_thread_class):
+ self._subject.start()
+ dummy_request = _make_dummy_check_request(self.PROJECT_ID,
+ self.SERVICE_NAME)
+ self._mock_transport.services.check.side_effect = lambda: 1/0
+ expect(self._subject.check(dummy_request)).to(be_none)
+
+
+class TestClientReport(unittest2.TestCase):
+ SERVICE_NAME = 'report'
+ PROJECT_ID = SERVICE_NAME + '.project'
+
+ def setUp(self):
+ self._mock_transport = mock.MagicMock()
+ self._subject = client.Loaders.DEFAULT.load(
+ self.SERVICE_NAME,
+ create_transport=lambda: self._mock_transport)
+
+ def test_should_raise_on_report_without_start(self):
+ dummy_request = _make_dummy_report_request(self.PROJECT_ID,
+ self.SERVICE_NAME)
+ expect(lambda: self._subject.report(dummy_request)).to(
+ raise_error(AssertionError))
+
+ @mock.patch("google.api.control.client._THREAD_CLASS", spec=True)
+ def test_should_not_send_the_request_if_cached(self, dummy_thread_class):
+ t = self._mock_transport
+ self._subject.start()
+ dummy_request = _make_dummy_report_request(self.PROJECT_ID,
+ self.SERVICE_NAME)
+ self._subject.report(dummy_request)
+ expect(t.services.report.called).to(be_false)
+
+ @mock.patch("google.api.control.client._THREAD_CLASS", spec=True)
+ def test_should_send_a_request_if_not_cached(self, dummy_thread_class):
+ self._subject = client.Loaders.NO_CACHE.load(
+ self.SERVICE_NAME,
+ create_transport=lambda: self._mock_transport)
+
+ t = self._mock_transport
+ self._subject.start()
+ dummy_request = _make_dummy_report_request(self.PROJECT_ID,
+ self.SERVICE_NAME)
+ self._subject.report(dummy_request)
+ expect(t.services.report.called).to(be_true)
+
+ @mock.patch("google.api.control.client._THREAD_CLASS", spec=True)
+ def test_should_ignore_bad_transport_when_not_cached(self, dummy_thread_class):
+ self._subject = client.Loaders.NO_CACHE.load(
+ self.SERVICE_NAME,
+ create_transport=lambda: self._mock_transport)
+
+ self._mock_transport.services.report.side_effect = lambda: 1/0
+ self._subject.start()
+ dummy_request = _make_dummy_report_request(self.PROJECT_ID,
+ self.SERVICE_NAME)
+ self._subject.report(dummy_request)
+ expect(self._mock_transport.services.report.called).to(be_true)
+
+
+class TestNoSchedulerThread(unittest2.TestCase):
+ SERVICE_NAME = 'no-scheduler-thread'
+ PROJECT_ID = SERVICE_NAME + '.project'
+
+ def setUp(self):
+ self._timer = _DateTimeTimer()
+ self._mock_transport = mock.MagicMock()
+ self._subject = client.Loaders.DEFAULT.load(
+ self.SERVICE_NAME,
+ create_transport=lambda: self._mock_transport,
+ timer=self._timer)
+ self._no_cache_subject = client.Loaders.NO_CACHE.load(
+ self.SERVICE_NAME,
+ create_transport=lambda: self._mock_transport,
+ timer=self._timer)
+
+ @mock.patch("google.api.control.client._THREAD_CLASS", spec=True)
+ @mock.patch("google.api.control.client.sched", spec=True)
+ def test_should_initialize_scheduler(self, sched, thread_class):
+ thread_class.return_value.start.side_effect = lambda: 1/0
+ for s in (self._subject, self._no_cache_subject):
+ s.start()
+ expect(sched.scheduler.called).to(be_true)
+ sched.reset_mock()
+
+ @mock.patch("google.api.control.client._THREAD_CLASS", spec=True)
+ @mock.patch("google.api.control.client.sched", spec=True)
+ def test_should_not_enter_scheduler_when_there_is_no_cache(self, sched, thread_class):
+ thread_class.return_value.start.side_effect = lambda: 1/0
+ self._no_cache_subject.start()
+ expect(sched.scheduler.called).to(be_true)
+ scheduler = sched.scheduler.return_value
+ expect(scheduler.enter.called).to(be_false)
+
+ @mock.patch("google.api.control.client._THREAD_CLASS", spec=True)
+ @mock.patch("google.api.control.client.sched", spec=True)
+ def test_should_enter_scheduler_when_there_is_a_cache(self, sched, thread_class):
+ thread_class.return_value.start.side_effect = lambda: 1/0
+ self._subject.start()
+ expect(sched.scheduler.called).to(be_true)
+ scheduler = sched.scheduler.return_value
+ expect(scheduler.enter.called).to(be_true)
+
+ @mock.patch("google.api.control.client._THREAD_CLASS", spec=True)
+ @mock.patch("google.api.control.client.sched", spec=True)
+ def test_should_not_enter_scheduler_for_cached_checks(self, sched, thread_class):
+ thread_class.return_value.start.side_effect = lambda: 1/0
+ self._subject.start()
+
+ # confirm scheduler is created and initialized
+ expect(sched.scheduler.called).to(be_true)
+ scheduler = sched.scheduler.return_value
+ expect(scheduler.enter.called).to(be_true)
+ scheduler.reset_mock()
+
+ # call check once, to a cache response
+ dummy_request = _make_dummy_check_request(self.PROJECT_ID,
+ self.SERVICE_NAME)
+ dummy_response = messages.CheckResponse(
+ operationId=dummy_request.checkRequest.operation.operationId)
+ t = self._mock_transport
+ t.services.check.return_value = dummy_response
+ expect(self._subject.check(dummy_request)).to(equal(dummy_response))
+ t.reset_mock()
+
+ # call check again - response is cached...
+ expect(self._subject.check(dummy_request)).to(equal(dummy_response))
+ expect(self._mock_transport.services.check.called).to(be_false)
+
+ # ... the scheduler is not run
+ expect(scheduler.run.called).to(be_false)
+
+ @mock.patch("google.api.control.client._THREAD_CLASS", spec=True)
+ @mock.patch("google.api.control.client.sched", spec=True)
+ def test_should_enter_scheduler_for_aggregated_reports(self, sched, thread_class):
+ thread_class.return_value.start.side_effect = lambda: 1/0
+ self._subject.start()
+
+ # confirm scheduler is created and initialized
+ expect(sched.scheduler.called).to(be_true)
+ scheduler = sched.scheduler.return_value
+ expect(scheduler.enter.called).to(be_true)
+ scheduler.reset_mock()
+
+ # call report once; transport is not called, but the scheduler is run
+ dummy_request = _make_dummy_report_request(self.PROJECT_ID,
+ self.SERVICE_NAME)
+ self._subject.report(dummy_request)
+ expect(self._mock_transport.services.report.called).to(be_false)
+ expect(scheduler.run.called).to(be_true)
+
+ @mock.patch("google.api.control.client._THREAD_CLASS", spec=True)
+ def test_should_flush_report_cache_in_scheduler(self, thread_class):
+ thread_class.return_value.start.side_effect = lambda: 1/0
+ self._subject.start()
+
+ # call report once; transport is not called
+ dummy_request = _make_dummy_report_request(self.PROJECT_ID,
+ self.SERVICE_NAME)
+ self._subject.report(dummy_request) # cached a report
+ expect(self._mock_transport.services.report.called).to(be_false)
+ # pass time, at least the flush interval, after which the report
+ # cache to flush
+ self._timer.tick()
+ self._timer.tick()
+ self._subject.report(dummy_request)
+ expect(self._mock_transport.services.report.called).to(be_true)
+
+ @mock.patch("google.api.control.client._THREAD_CLASS", spec=True)
+ @mock.patch("google.api.control.client.sched", spec=True)
+ def test_should_not_run_scheduler_when_stopping(self, sched, thread_class):
+ thread_class.return_value.start.side_effect = lambda: 1/0
+ self._subject.start()
+
+ # confirm scheduler is created and initialized
+ expect(sched.scheduler.called).to(be_true)
+ scheduler = sched.scheduler.return_value
+ expect(scheduler.enter.called).to(be_true)
+
+ # stop the subject. transport is called, but the scheduler is not run
+ self._subject.report(
+ _make_dummy_report_request(self.PROJECT_ID, self.SERVICE_NAME))
+ scheduler.reset_mock()
+ self._subject.stop()
+ expect(self._mock_transport.services.report.called).to(be_true)
+ expect(scheduler.run.called).to(be_false)
+
+
+class _DateTimeTimer(object):
+ def __init__(self, auto=False):
+ self.auto = auto
+ self.time = datetime.datetime.utcfromtimestamp(0)
+
+ def __call__(self):
+ if self.auto:
+ self.tick()
+ return self.time
+
+ def tick(self):
+ self.time += datetime.timedelta(seconds=1)
« no previous file with comments | « third_party/google-endpoints/test/test_check_request.py ('k') | third_party/google-endpoints/test/test_distribution.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698