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

Side by Side Diff: appengine/swarming/server/task_scheduler_test.py

Issue 2012843003: Remove use of search API; effectively remove support to search for task by name. (Closed) Base URL: git@github.com:luci/luci-py.git@master
Patch Set: . Created 4 years, 7 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 unified diff | Download patch
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright 2014 The LUCI Authors. All rights reserved. 2 # Copyright 2014 The LUCI Authors. All rights reserved.
3 # Use of this source code is governed under the Apache License, Version 2.0 3 # Use of this source code is governed under the Apache License, Version 2.0
4 # that can be found in the LICENSE file. 4 # that can be found in the LICENSE file.
5 5
6 import datetime 6 import datetime
7 import inspect 7 import inspect
8 import logging 8 import logging
9 import os 9 import os
10 import random 10 import random
11 import sys 11 import sys
12 import unittest 12 import unittest
13 13
14 import test_env 14 import test_env
15 test_env.setup_test_env() 15 test_env.setup_test_env()
16 16
17 from google.appengine.api import datastore_errors 17 from google.appengine.api import datastore_errors
18 from google.appengine.api import search
19 from google.appengine.ext import deferred 18 from google.appengine.ext import deferred
20 from google.appengine.ext import ndb 19 from google.appengine.ext import ndb
21 20
22 import webtest 21 import webtest
23 22
24 from components import auth_testing 23 from components import auth_testing
25 from components import datastore_utils 24 from components import datastore_utils
26 from components import pubsub 25 from components import pubsub
27 from components import stats_framework 26 from components import stats_framework
28 from components import utils 27 from components import utils
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 reaped_request, run_result = task_scheduler.bot_reap_task( 92 reaped_request, run_result = task_scheduler.bot_reap_task(
94 {'OS': 'Windows-3.1.1', u'pool': u'default'}, 'localhost', 'abc', None) 93 {'OS': 'Windows-3.1.1', u'pool': u'default'}, 'localhost', 'abc', None)
95 return run_result 94 return run_result
96 95
97 96
98 class TaskSchedulerApiTest(test_case.TestCase): 97 class TaskSchedulerApiTest(test_case.TestCase):
99 APP_DIR = test_env.APP_DIR 98 APP_DIR = test_env.APP_DIR
100 99
101 def setUp(self): 100 def setUp(self):
102 super(TaskSchedulerApiTest, self).setUp() 101 super(TaskSchedulerApiTest, self).setUp()
103 self.testbed.init_search_stub()
104
105 self.now = datetime.datetime(2014, 1, 2, 3, 4, 5, 6) 102 self.now = datetime.datetime(2014, 1, 2, 3, 4, 5, 6)
106 self.mock_now(self.now) 103 self.mock_now(self.now)
107 self.app = webtest.TestApp( 104 self.app = webtest.TestApp(
108 deferred.application, 105 deferred.application,
109 extra_environ={ 106 extra_environ={
110 'REMOTE_ADDR': '1.0.1.2', 107 'REMOTE_ADDR': '1.0.1.2',
111 'SERVER_SOFTWARE': os.environ['SERVER_SOFTWARE'], 108 'SERVER_SOFTWARE': os.environ['SERVER_SOFTWARE'],
112 }) 109 })
113 self.mock(stats_framework, 'add_entry', self._parse_line) 110 self.mock(stats_framework, 'add_entry', self._parse_line)
114 auth_testing.mock_get_current_identity(self) 111 auth_testing.mock_get_current_identity(self)
(...skipping 1512 matching lines...) Expand 10 before | Expand all | Expand 10 after
1627 } 1624 }
1628 _request, run_result = task_scheduler.bot_reap_task( 1625 _request, run_result = task_scheduler.bot_reap_task(
1629 bot_dimensions, 'localhost', 'abc', None) 1626 bot_dimensions, 'localhost', 'abc', None)
1630 self.assertEqual(1, run_result.try_number) 1627 self.assertEqual(1, run_result.try_number)
1631 self.assertEqual(task_result.State.RUNNING, run_result.state) 1628 self.assertEqual(task_result.State.RUNNING, run_result.state)
1632 self.mock_now(self.now + task_result.BOT_PING_TOLERANCE, 601) 1629 self.mock_now(self.now + task_result.BOT_PING_TOLERANCE, 601)
1633 self.assertEqual( 1630 self.assertEqual(
1634 (['1d69b9f088008811'], 0, 0), 1631 (['1d69b9f088008811'], 0, 0),
1635 task_scheduler.cron_handle_bot_died('f.local')) 1632 task_scheduler.cron_handle_bot_died('f.local'))
1636 1633
1637 def test_search_by_name(self):
1638 # This is awkward but it's because _search_by_name() depends on
1639 # functionality saved by task_scheduler. (There's a layering issue).
1640 data = _gen_request(
1641 properties={
1642 'dimensions': {u'OS': u'Windows-3.1.1', u'pool': u'default'},
1643 })
1644 request = task_request.make_request(data, True)
1645 result_summary = task_scheduler.schedule_request(request)
1646
1647 # Assert that search is not case-sensitive by using unexpected casing.
1648 actual, _cursor = task_result._search_by_name('requEST', None, 10)
1649 self.assertEqual([result_summary], actual)
1650 actual, _cursor = task_result._search_by_name('name', None, 10)
1651 self.assertEqual([result_summary], actual)
1652
1653 def test_search_by_name_failures(self):
1654 data = _gen_request(
1655 properties={
1656 'dimensions': {u'OS': u'Windows-3.1.1', u'pool': u'default'},
1657 })
1658 request = task_request.make_request(data, True)
1659 result_summary = task_scheduler.schedule_request(request)
1660
1661 actual, _cursor = task_result._search_by_name('foo', None, 10)
1662 self.assertEqual([], actual)
1663 # Partial match doesn't work.
1664 actual, _cursor = task_result._search_by_name('nam', None, 10)
1665 self.assertEqual([], actual)
1666
1667 def test_search_by_name_broken_tasks(self):
1668 # Create tasks where task_scheduler.schedule_request() fails in the middle.
1669 # This is done by mocking the functions to fail every SKIP call and running
1670 # it in a loop.
1671 class RandomFailure(Exception):
1672 pass
1673
1674 # First call fails ndb.put_multi(), second call fails search.Index.put(),
1675 # third call work.
1676 index = [0]
1677 SKIP = 3
1678 def put_multi(*args, **kwargs):
1679 callers = [i[3] for i in inspect.stack()]
1680 self.assertTrue(
1681 'make_request' in callers or 'schedule_request' in callers, callers)
1682 if (index[0] % SKIP) == 1:
1683 raise RandomFailure()
1684 return old_put_multi(*args, **kwargs)
1685
1686 def put_async(*args, **kwargs):
1687 callers = [i[3] for i in inspect.stack()]
1688 self.assertIn('schedule_request', callers)
1689 out = ndb.Future()
1690 if (index[0] % SKIP) == 2:
1691 out.set_exception(search.Error())
1692 else:
1693 out.set_result(old_put_async(*args, **kwargs).get_result())
1694 return out
1695
1696 old_put_multi = self.mock(ndb, 'put_multi', put_multi)
1697 old_put_async = self.mock(search.Index, 'put_async', put_async)
1698
1699 saved = []
1700
1701 for i in xrange(100):
1702 index[0] = i
1703 data = _gen_request(
1704 name='Request %d' % i,
1705 properties={
1706 'dimensions': {u'OS': u'Windows-3.1.1', u'pool': u'default'},
1707 })
1708 try:
1709 request = task_request.make_request(data, True)
1710 result_summary = task_scheduler.schedule_request(request)
1711 saved.append(result_summary)
1712 except RandomFailure:
1713 pass
1714
1715 self.assertEqual(67, len(saved))
1716 self.assertEqual(100, task_request.TaskRequest.query().count())
1717 self.assertEqual(67, task_result.TaskResultSummary.query().count())
1718
1719 # Now the DB is full of half-corrupted entities.
1720 cursor = None
1721 actual, cursor = task_result._search_by_name('Request', cursor, 31)
1722 self.assertEqual(31, len(actual))
1723 actual, cursor = task_result._search_by_name('Request', cursor, 31)
1724 self.assertEqual(3, len(actual))
1725 actual, cursor = task_result._search_by_name('Request', cursor, 31)
1726 self.assertEqual(0, len(actual))
1727
1728 1634
1729 if __name__ == '__main__': 1635 if __name__ == '__main__':
1730 if '-v' in sys.argv: 1636 if '-v' in sys.argv:
1731 unittest.TestCase.maxDiff = None 1637 unittest.TestCase.maxDiff = None
1732 logging.basicConfig( 1638 logging.basicConfig(
1733 level=logging.DEBUG if '-v' in sys.argv else logging.CRITICAL) 1639 level=logging.DEBUG if '-v' in sys.argv else logging.CRITICAL)
1734 unittest.main() 1640 unittest.main()
OLDNEW
« no previous file with comments | « appengine/swarming/server/task_scheduler.py ('k') | appengine/swarming/templates/user_tasks.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698