Repository: aurora Updated Branches: refs/heads/master 0dd096dc5 -> bafdd71a0
Removing unused quota_check.py Reviewed at https://reviews.apache.org/r/46045/ Project: http://git-wip-us.apache.org/repos/asf/aurora/repo Commit: http://git-wip-us.apache.org/repos/asf/aurora/commit/bafdd71a Tree: http://git-wip-us.apache.org/repos/asf/aurora/tree/bafdd71a Diff: http://git-wip-us.apache.org/repos/asf/aurora/diff/bafdd71a Branch: refs/heads/master Commit: bafdd71a01504be18d033cc67e2b74d5816f8be1 Parents: 0dd096d Author: Maxim Khutornenko <[email protected]> Authored: Mon Apr 11 14:43:47 2016 -0700 Committer: Maxim Khutornenko <[email protected]> Committed: Mon Apr 11 14:43:47 2016 -0700 ---------------------------------------------------------------------- .../apache/aurora/client/api/quota_check.py | 130 ----------------- .../aurora/client/api/test_quota_check.py | 142 ------------------- 2 files changed, 272 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/aurora/blob/bafdd71a/src/main/python/apache/aurora/client/api/quota_check.py ---------------------------------------------------------------------- diff --git a/src/main/python/apache/aurora/client/api/quota_check.py b/src/main/python/apache/aurora/client/api/quota_check.py deleted file mode 100644 index a3252e5..0000000 --- a/src/main/python/apache/aurora/client/api/quota_check.py +++ /dev/null @@ -1,130 +0,0 @@ -# -# 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 math -import operator -from copy import deepcopy - -from twitter.common import log - -from apache.aurora.client.base import combine_messages - -from gen.apache.aurora.api.ttypes import ResourceAggregate, Response, ResponseCode, ResponseDetail - - -class CapacityRequest(object): - """Facilitates Quota manipulations.""" - - @classmethod - def from_task(cls, task): - return cls(ResourceAggregate(numCpus=task.numCpus, ramMb=task.ramMb, diskMb=task.diskMb)) - - def __init__(self, quota=None): - self._quota = quota or ResourceAggregate(numCpus=0.0, ramMb=0, diskMb=0) - - def __add__(self, other): - return self._op(operator.__add__, other) - - def __radd__(self, other): - return self._op(operator.__add__, other) - - def __sub__(self, other): - return self._op(operator.__sub__, other) - - def __eq__(self, other): - return self._quota == other._quota - - def _op(self, op, other): - if not isinstance(other, CapacityRequest): - return self - - return CapacityRequest( - ResourceAggregate(numCpus=op(self._quota.numCpus, other._quota.numCpus), - ramMb=op(self._quota.ramMb, other._quota.ramMb), - diskMb=op(self._quota.diskMb, other._quota.diskMb))) - - def valid(self): - return self._quota.numCpus >= 0.0 and self._quota.ramMb >= 0 and self._quota.diskMb >= 0 - - def invert_or_reset(self): - """Inverts negative resource and resets positive resource as zero.""" - def invert_or_reset(val): - return math.fabs(val) if val < 0 else 0 - - return CapacityRequest(ResourceAggregate( - numCpus=invert_or_reset(self._quota.numCpus), - ramMb=invert_or_reset(self._quota.ramMb), - diskMb=invert_or_reset(self._quota.diskMb))) - - def quota(self): - return deepcopy(self._quota) - - -class QuotaCheck(object): - """Performs quota checks for the provided job/task configurations.""" - - def __init__(self, scheduler): - self._scheduler = scheduler - - def validate_quota_from_requested(self, job_key, production, released, acquired): - """Validates requested change will not exceed the available quota. - - Arguments: - job_key -- job key. - production -- production flag. - released -- production CapacityRequest to be released (in case of job update). - acquired -- production CapacityRequest to be acquired. - - Returns: ResponseCode.OK if check is successful. - """ - # TODO(wfarner): Avoid synthesizing scheduler responses. - resp_ok = Response( - responseCode=ResponseCode.OK, - details=[ResponseDetail(message='Quota check successful.')]) - if not production: - return resp_ok - - resp = self._scheduler.getQuota(job_key.role) - if resp.responseCode != ResponseCode.OK: - log.error('Failed to get quota from scheduler: %s' % combine_messages(resp)) - return resp - - allocated = CapacityRequest(resp.result.getQuotaResult.quota) - consumed = CapacityRequest(resp.result.getQuotaResult.prodSharedConsumption) - requested = acquired - released - effective = allocated - consumed - requested - - if not effective.valid(): - log.info('Not enough quota to create/update job.') - print_quota(allocated.quota(), 'Total allocated quota', job_key.role) - print_quota(consumed.quota(), 'Consumed quota', job_key.role) - print_quota(requested.quota(), 'Requested', job_key.name) - print_quota(effective.invert_or_reset().quota(), 'Additional quota required', job_key.role) - - # TODO(wfarner): Avoid synthesizing scheduler responses. - return Response( - responseCode=ResponseCode.INVALID_REQUEST, - details=[ResponseDetail(message='Failed quota check.')]) - - return resp_ok - - -def print_quota(quota, msg, subj): - quota_fields = [ - ('CPU', quota.numCpus), - ('RAM', '%f GB' % (float(quota.ramMb) / 1024)), - ('Disk', '%f GB' % (float(quota.diskMb) / 1024)) - ] - log.info('%s for %s:\n\t%s' % - (msg, subj, '\n\t'.join(['%s\t%s' % (k, v) for (k, v) in quota_fields]))) http://git-wip-us.apache.org/repos/asf/aurora/blob/bafdd71a/src/test/python/apache/aurora/client/api/test_quota_check.py ---------------------------------------------------------------------- diff --git a/src/test/python/apache/aurora/client/api/test_quota_check.py b/src/test/python/apache/aurora/client/api/test_quota_check.py deleted file mode 100644 index 0b97334..0000000 --- a/src/test/python/apache/aurora/client/api/test_quota_check.py +++ /dev/null @@ -1,142 +0,0 @@ -# -# 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 unittest -from copy import deepcopy - -from mock import call, create_autospec, patch - -from apache.aurora.client.api.quota_check import CapacityRequest, QuotaCheck, print_quota - -from ...api_util import SchedulerThriftApiSpec - -from gen.apache.aurora.api.ttypes import ( - GetQuotaResult, - JobKey, - ResourceAggregate, - Response, - ResponseCode, - ResponseDetail, - Result -) - - -class QuotaCheckTest(unittest.TestCase): - def setUp(self): - self._scheduler = create_autospec(spec=SchedulerThriftApiSpec, instance=True) - self._quota_checker = QuotaCheck(self._scheduler) - self._role = 'mesos' - self._name = 'quotajob' - self._env = 'test' - self._job_key = JobKey(name=self._name, environment=self._env, role=self._role) - - def mock_get_quota(self, allocated, consumed, response_code=None): - response_code = ResponseCode.OK if response_code is None else response_code - - resp = Response(responseCode=response_code, details=[ResponseDetail(message='test')]) - resp.result = Result( - getQuotaResult=GetQuotaResult( - quota=deepcopy(allocated), prodSharedConsumption=deepcopy(consumed))) - self._scheduler.getQuota.return_value = resp - - def assert_result(self, prod, released, acquired, expected_code=None): - expected_code = ResponseCode.OK if expected_code is None else expected_code - resp = self._quota_checker.validate_quota_from_requested( - self._job_key, - prod, - released, - acquired) - assert expected_code == resp.responseCode, ( - 'Expected response:%s Actual response:%s' % (expected_code, resp.responseCode)) - if prod: - self._scheduler.getQuota.assert_called_once_with(self._role) - else: - assert not self._scheduler.getQuota.called, 'Scheduler.getQuota() unexpected call.' - - def test_pass(self): - allocated = ResourceAggregate(numCpus=50.0, ramMb=1000, diskMb=3000) - consumed = ResourceAggregate(numCpus=25.0, ramMb=500, diskMb=2000) - released = CapacityRequest(ResourceAggregate(numCpus=5.0, ramMb=100, diskMb=500)) - acquired = CapacityRequest(ResourceAggregate(numCpus=15.0, ramMb=300, diskMb=800)) - - self.mock_get_quota(allocated, consumed) - self.assert_result(True, released, acquired) - - def test_pass_with_no_consumed(self): - allocated = ResourceAggregate(numCpus=50.0, ramMb=1000, diskMb=3000) - released = CapacityRequest(ResourceAggregate(numCpus=5.0, ramMb=100, diskMb=500)) - acquired = CapacityRequest(ResourceAggregate(numCpus=15.0, ramMb=300, diskMb=800)) - - self.mock_get_quota(allocated, None) - self.assert_result(True, released, acquired) - - def test_pass_due_to_released(self): - allocated = ResourceAggregate(numCpus=50.0, ramMb=1000, diskMb=3000) - consumed = ResourceAggregate(numCpus=45.0, ramMb=900, diskMb=2900) - released = CapacityRequest(ResourceAggregate(numCpus=5.0, ramMb=100, diskMb=100)) - acquired = CapacityRequest(ResourceAggregate(numCpus=10.0, ramMb=200, diskMb=200)) - - self.mock_get_quota(allocated, consumed) - self.assert_result(True, released, acquired) - - def test_skipped(self): - self.assert_result(False, None, None) - - def test_fail(self): - allocated = ResourceAggregate(numCpus=50.0, ramMb=1000, diskMb=3000) - consumed = ResourceAggregate(numCpus=25.0, ramMb=500, diskMb=2000) - released = CapacityRequest(ResourceAggregate(numCpus=5.0, ramMb=100, diskMb=500)) - acquired = CapacityRequest(ResourceAggregate(numCpus=35.0, ramMb=300, diskMb=800)) - - self.mock_get_quota(allocated, consumed) - self.assert_result(True, released, acquired, ResponseCode.INVALID_REQUEST) - - def test_fail_scheduler_call(self): - allocated = ResourceAggregate(numCpus=50.0, ramMb=1000, diskMb=3000) - consumed = ResourceAggregate(numCpus=25.0, ramMb=500, diskMb=2000) - released = CapacityRequest(ResourceAggregate(numCpus=5.0, ramMb=100, diskMb=500)) - acquired = CapacityRequest(ResourceAggregate(numCpus=1.0, ramMb=100, diskMb=100)) - - self.mock_get_quota(allocated, consumed, response_code=ResponseCode.INVALID_REQUEST) - self.assert_result(True, released, acquired, ResponseCode.INVALID_REQUEST) - - @patch('apache.aurora.client.api.quota_check.print_quota', spec=print_quota) - def test_additional_quota_out(self, mock_print_quota): - allocated = ResourceAggregate(numCpus=50.0, ramMb=1000, diskMb=3000) - consumed = ResourceAggregate(numCpus=45.0, ramMb=900, diskMb=2900) - released = CapacityRequest(ResourceAggregate(numCpus=5.0, ramMb=100, diskMb=100)) - acquired = CapacityRequest(ResourceAggregate(numCpus=11.0, ramMb=220, diskMb=200)) - additional = ResourceAggregate(numCpus=1.0, ramMb=20, diskMb=0) - - self.mock_get_quota(allocated, consumed) - self.assert_result(True, released, acquired, ResponseCode.INVALID_REQUEST) - assert mock_print_quota.mock_calls[:4] == [ - call(allocated, 'Total allocated quota', self._role), - call(consumed, 'Consumed quota', self._role), - call((acquired - released).quota(), 'Requested', self._name), - call(additional, 'Additional quota required', self._role) - ] - - def test_op_not_cap_request(self): - released = CapacityRequest(ResourceAggregate(numCpus=5.0, ramMb=100, diskMb=100)) - # Should return self so a noop. - out = released._op('not_a_real_op', 'not_a_CapacityRequest_obj') - self.assertEqual(out, released) - - def test_right_add(self): - released = CapacityRequest(ResourceAggregate(numCpus=5.0, ramMb=100, diskMb=100)) - # Testing __radd__ which is called when object on the ride side isn't our CapacityRequest - # instance. - out = 1 + released - self.assertEqual(out, released)
