| OLD | NEW |
| 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 logging | 7 import logging |
| 8 import os | 8 import os |
| 9 import random | 9 import random |
| 10 import sys | 10 import sys |
| (...skipping 1590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1601 ], | 1601 ], |
| 1602 'try_number': 2, | 1602 'try_number': 2, |
| 1603 'user': u'Jesus', | 1603 'user': u'Jesus', |
| 1604 } | 1604 } |
| 1605 self.assertEqual(expected, run_result.result_summary_key.get().to_dict()) | 1605 self.assertEqual(expected, run_result.result_summary_key.get().to_dict()) |
| 1606 self.assertEqual(0.1, run_result.key.get().cost_usd) | 1606 self.assertEqual(0.1, run_result.key.get().cost_usd) |
| 1607 | 1607 |
| 1608 self.assertEqual(0, self.execute_tasks()) | 1608 self.assertEqual(0, self.execute_tasks()) |
| 1609 self.assertEqual(4, len(pub_sub_calls)) # RUNNING -> COMPLETED | 1609 self.assertEqual(4, len(pub_sub_calls)) # RUNNING -> COMPLETED |
| 1610 | 1610 |
| 1611 def test_cron_handle_bot_died_no_update_not_idempotent(self): |
| 1612 pub_sub_calls = self.mock_pub_sub() |
| 1613 |
| 1614 # Test first retry, then success. |
| 1615 now = utils.utcnow() |
| 1616 request = self._gen_request( |
| 1617 properties={ |
| 1618 'dimensions': {u'os': u'Windows-3.1.1', u'pool': u'default'}, |
| 1619 }, |
| 1620 created_ts=now, |
| 1621 expiration_ts=now+datetime.timedelta(seconds=600), |
| 1622 pubsub_topic='projects/abc/topics/def') |
| 1623 task_request.init_new_request(request, True, None) |
| 1624 _result_summary = task_scheduler.schedule_request(request, None) |
| 1625 self.assertEqual(1, self.execute_tasks()) |
| 1626 self.assertEqual(0, len(pub_sub_calls)) |
| 1627 bot_dimensions = { |
| 1628 u'foo': [u'bar'], |
| 1629 u'id': [u'localhost'], |
| 1630 u'os': [u'Windows', u'Windows-3.1.1'], |
| 1631 u'pool': [u'default'], |
| 1632 } |
| 1633 self._register_bot(bot_dimensions, nb_task=0) |
| 1634 request, _, run_result = task_scheduler.bot_reap_task( |
| 1635 bot_dimensions, 'abc', None) |
| 1636 self.assertEqual( |
| 1637 task_result.State.RUNNING, run_result.result_summary_key.get().state) |
| 1638 self.assertEqual(1, self.execute_tasks()) |
| 1639 self.assertEqual(1, len(pub_sub_calls)) # PENDING -> RUNNING |
| 1640 self.assertEqual(1, run_result.try_number) |
| 1641 self.assertEqual(task_result.State.RUNNING, run_result.state) |
| 1642 now_1 = self.mock_now(self.now + task_result.BOT_PING_TOLERANCE, 1) |
| 1643 self.assertEqual(([], 1, 0), task_scheduler.cron_handle_bot_died('f.local')) |
| 1644 self.assertEqual(1, self.execute_tasks()) |
| 1645 self.assertEqual(2, len(pub_sub_calls)) # RUNNING -> PENDING |
| 1646 |
| 1647 # Refresh and compare: |
| 1648 expected = { |
| 1649 'abandoned_ts': now_1, |
| 1650 'bot_dimensions': bot_dimensions, |
| 1651 'bot_id': u'localhost', |
| 1652 'bot_version': u'abc', |
| 1653 'cipd_pins': None, |
| 1654 'children_task_ids': [], |
| 1655 'completed_ts': None, |
| 1656 'cost_usd': 0., |
| 1657 'duration': None, |
| 1658 'exit_code': None, |
| 1659 'failure': False, |
| 1660 'id': '1d69b9f088008911', |
| 1661 'internal_failure': True, |
| 1662 'modified_ts': now_1, |
| 1663 'outputs_ref': None, |
| 1664 'server_versions': [u'v1a'], |
| 1665 'started_ts': self.now, |
| 1666 'state': task_result.State.BOT_DIED, |
| 1667 'try_number': 1, |
| 1668 } |
| 1669 self.assertEqual(expected, run_result.key.get().to_dict()) |
| 1670 expected = { |
| 1671 'abandoned_ts': None, |
| 1672 'bot_dimensions': bot_dimensions, |
| 1673 'bot_id': u'localhost', |
| 1674 'bot_version': u'abc', |
| 1675 'cipd_pins': None, |
| 1676 'children_task_ids': [], |
| 1677 'completed_ts': None, |
| 1678 'costs_usd': [0.], |
| 1679 'cost_saved_usd': None, |
| 1680 'created_ts': self.now, |
| 1681 'deduped_from': None, |
| 1682 'duration': None, |
| 1683 'exit_code': None, |
| 1684 'failure': False, |
| 1685 'id': '1d69b9f088008910', |
| 1686 'internal_failure': False, |
| 1687 'modified_ts': now_1, |
| 1688 'name': u'Request name', |
| 1689 'outputs_ref': None, |
| 1690 'properties_hash': None, |
| 1691 'server_versions': [u'v1a'], |
| 1692 'started_ts': None, |
| 1693 'state': task_result.State.PENDING, |
| 1694 'tags': [ |
| 1695 u'os:Windows-3.1.1', |
| 1696 u'pool:default', |
| 1697 u'priority:50', |
| 1698 u'service_account:none', |
| 1699 u'tag:1', |
| 1700 u'user:Jesus', |
| 1701 ], |
| 1702 'try_number': 1, |
| 1703 'user': u'Jesus', |
| 1704 } |
| 1705 self.assertEqual(expected, run_result.result_summary_key.get().to_dict()) |
| 1706 |
| 1707 # Task was retried. |
| 1708 now_2 = self.mock_now(self.now + task_result.BOT_PING_TOLERANCE, 2) |
| 1709 bot_dimensions_second = bot_dimensions.copy() |
| 1710 bot_dimensions_second[u'id'] = [u'localhost-second'] |
| 1711 self._register_bot(bot_dimensions_second, nb_task=0) |
| 1712 _request, _, run_result = task_scheduler.bot_reap_task( |
| 1713 bot_dimensions_second, 'abc', None) |
| 1714 self.assertEqual(1, self.execute_tasks()) |
| 1715 self.assertEqual(3, len(pub_sub_calls)) # PENDING -> RUNNING |
| 1716 logging.info('%s', [t.to_dict() for t in task_to_run.TaskToRun.query()]) |
| 1717 self.assertEqual(2, run_result.try_number) |
| 1718 self.assertEqual( |
| 1719 task_result.State.COMPLETED, |
| 1720 task_scheduler.bot_update_task( |
| 1721 run_result_key=run_result.key, |
| 1722 bot_id='localhost-second', |
| 1723 cipd_pins=None, |
| 1724 output='Foo1', |
| 1725 output_chunk_start=0, |
| 1726 exit_code=0, |
| 1727 duration=0.1, |
| 1728 hard_timeout=False, |
| 1729 io_timeout=False, |
| 1730 cost_usd=0.1, |
| 1731 outputs_ref=None, |
| 1732 performance_stats=None)) |
| 1733 expected = { |
| 1734 'abandoned_ts': None, |
| 1735 'bot_dimensions': bot_dimensions_second, |
| 1736 'bot_id': u'localhost-second', |
| 1737 'bot_version': u'abc', |
| 1738 'cipd_pins': None, |
| 1739 'children_task_ids': [], |
| 1740 'completed_ts': now_2, |
| 1741 'costs_usd': [0., 0.1], |
| 1742 'cost_saved_usd': None, |
| 1743 'created_ts': self.now, |
| 1744 'deduped_from': None, |
| 1745 'duration': 0.1, |
| 1746 'exit_code': 0, |
| 1747 'failure': False, |
| 1748 'id': '1d69b9f088008910', |
| 1749 'internal_failure': False, |
| 1750 'modified_ts': now_2, |
| 1751 'name': u'Request name', |
| 1752 'outputs_ref': None, |
| 1753 'properties_hash': None, |
| 1754 'server_versions': [u'v1a'], |
| 1755 'started_ts': now_2, |
| 1756 'state': task_result.State.COMPLETED, |
| 1757 'tags': [ |
| 1758 u'os:Windows-3.1.1', |
| 1759 u'pool:default', |
| 1760 u'priority:50', |
| 1761 u'service_account:none', |
| 1762 u'tag:1', |
| 1763 u'user:Jesus', |
| 1764 ], |
| 1765 'try_number': 2, |
| 1766 'user': u'Jesus', |
| 1767 } |
| 1768 self.assertEqual(expected, run_result.result_summary_key.get().to_dict()) |
| 1769 self.assertEqual(0.1, run_result.key.get().cost_usd) |
| 1770 |
| 1771 self.assertEqual(0, self.execute_tasks()) |
| 1772 self.assertEqual(4, len(pub_sub_calls)) # RUNNING -> COMPLETED |
| 1773 |
| 1611 def test_cron_handle_bot_died_same_bot_denied(self): | 1774 def test_cron_handle_bot_died_same_bot_denied(self): |
| 1612 # Test first retry, then success. | 1775 # Test first retry, then success. |
| 1613 now = utils.utcnow() | 1776 now = utils.utcnow() |
| 1614 request = self._gen_request( | 1777 request = self._gen_request( |
| 1615 properties={ | 1778 properties={ |
| 1616 'dimensions': {u'os': u'Windows-3.1.1', u'pool': u'default'}, | 1779 'dimensions': {u'os': u'Windows-3.1.1', u'pool': u'default'}, |
| 1617 'idempotent': True, | 1780 'idempotent': True, |
| 1618 }, | 1781 }, |
| 1619 created_ts=now, | 1782 created_ts=now, |
| 1620 expiration_ts=now+datetime.timedelta(seconds=600)) | 1783 expiration_ts=now+datetime.timedelta(seconds=600)) |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1803 (['1d69b9f088008911'], 0, 0), | 1966 (['1d69b9f088008911'], 0, 0), |
| 1804 task_scheduler.cron_handle_bot_died('f.local')) | 1967 task_scheduler.cron_handle_bot_died('f.local')) |
| 1805 | 1968 |
| 1806 | 1969 |
| 1807 if __name__ == '__main__': | 1970 if __name__ == '__main__': |
| 1808 if '-v' in sys.argv: | 1971 if '-v' in sys.argv: |
| 1809 unittest.TestCase.maxDiff = None | 1972 unittest.TestCase.maxDiff = None |
| 1810 logging.basicConfig( | 1973 logging.basicConfig( |
| 1811 level=logging.DEBUG if '-v' in sys.argv else logging.CRITICAL) | 1974 level=logging.DEBUG if '-v' in sys.argv else logging.CRITICAL) |
| 1812 unittest.main() | 1975 unittest.main() |
| OLD | NEW |