build rate limiting: tests
This commit is contained in:
parent
57770493fa
commit
eb69abff8b
3 changed files with 31 additions and 7 deletions
|
@ -77,10 +77,14 @@ class WorkQueue(object):
|
||||||
._available_jobs(now, name_match_query)
|
._available_jobs(now, name_match_query)
|
||||||
.where(~(QueueItem.queue_name << running_query)))
|
.where(~(QueueItem.queue_name << running_query)))
|
||||||
|
|
||||||
def num_available_jobs(self, available_min_time, prefix):
|
def num_available_jobs_between(self, available_min_time, available_max_time, prefix):
|
||||||
|
"""
|
||||||
|
Returns the number of available queue items with a given prefix between the two provided times.
|
||||||
|
"""
|
||||||
prefix = prefix.lstrip('/')
|
prefix = prefix.lstrip('/')
|
||||||
available = self._available_jobs(datetime.utcnow(),
|
available = self._available_jobs(available_max_time,
|
||||||
self._name_match_query() + prefix)
|
'/'.join([self._queue_name, prefix]) + '%')
|
||||||
|
|
||||||
return available.where(QueueItem.available_after >= available_min_time).count()
|
return available.where(QueueItem.available_after >= available_min_time).count()
|
||||||
|
|
||||||
def _name_match_query(self):
|
def _name_match_query(self):
|
||||||
|
|
|
@ -25,10 +25,13 @@ class MaximumBuildsQueuedException(Exception):
|
||||||
|
|
||||||
|
|
||||||
def start_build(repository, prepared_build, pull_robot_name=None):
|
def start_build(repository, prepared_build, pull_robot_name=None):
|
||||||
queue_item_prefix = '%s/%s' % repository.namespace_user.username, repository.name
|
queue_item_prefix = '%s/%s' % (repository.namespace_user.username, repository.name)
|
||||||
if MAX_BUILD_QUEUE_ITEMS > 0 and MAX_BUILD_QUEUE_SECS > 0:
|
if MAX_BUILD_QUEUE_ITEMS > 0 and MAX_BUILD_QUEUE_SECS > 0:
|
||||||
available_min = datetime.utcnow() - timedelta(seconds=-MAX_BUILD_QUEUE_SECS)
|
now = datetime.utcnow()
|
||||||
available_builds = dockerfile_build_queue.num_available_jobs(available_min, queue_item_prefix)
|
available_min = now - timedelta(seconds=MAX_BUILD_QUEUE_SECS)
|
||||||
|
available_builds = dockerfile_build_queue.num_available_jobs_between(available_min,
|
||||||
|
now,
|
||||||
|
queue_item_prefix)
|
||||||
if available_builds > MAX_BUILD_QUEUE_ITEMS:
|
if available_builds > MAX_BUILD_QUEUE_ITEMS:
|
||||||
raise MaximumBuildsQueuedException()
|
raise MaximumBuildsQueuedException()
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ import unittest
|
||||||
import json
|
import json
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
from datetime import datetime, timedelta
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
|
||||||
from app import app
|
from app import app
|
||||||
|
@ -182,6 +183,22 @@ class TestQueue(QueueTestCase):
|
||||||
self.assertIn(msg, seen)
|
self.assertIn(msg, seen)
|
||||||
|
|
||||||
|
|
||||||
|
def test_num_available_between(self):
|
||||||
|
now = datetime.utcnow()
|
||||||
|
self.queue.put(['abc', 'def'], self.TEST_MESSAGE_1, available_after=-10)
|
||||||
|
self.queue.put(['abc', 'ghi'], self.TEST_MESSAGE_2, available_after=-5)
|
||||||
|
|
||||||
|
# Partial results
|
||||||
|
count = self.queue.num_available_jobs_between(now-timedelta(seconds=8), now, 'abc')
|
||||||
|
self.assertEqual(1, count)
|
||||||
|
|
||||||
|
# All results
|
||||||
|
count = self.queue.num_available_jobs_between(now-timedelta(seconds=20), now, 'abc')
|
||||||
|
self.assertEqual(2, count)
|
||||||
|
|
||||||
|
# No results
|
||||||
|
count = self.queue.num_available_jobs_between(now, now, 'abc')
|
||||||
|
self.assertEqual(0, count)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
||||||
|
|
Reference in a new issue