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

Side by Side Diff: appengine/swarming/handlers_endpoints_test.py

Issue 2220373003: Allow botlist API call to respond to quarantined: and is_dead: (Closed) Base URL: https://chromium.googlesource.com/external/github.com/luci/luci-py@master
Patch Set: Fix one edge case Created 4 years, 4 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 # coding=utf-8 2 # coding=utf-8
3 # Copyright 2015 The LUCI Authors. All rights reserved. 3 # Copyright 2015 The LUCI Authors. All rights reserved.
4 # Use of this source code is governed under the Apache License, Version 2.0 4 # Use of this source code is governed under the Apache License, Version 2.0
5 # that can be found in the LICENSE file. 5 # that can be found in the LICENSE file.
6 6
7 import base64 7 import base64
8 import datetime 8 import datetime
9 import json 9 import json
10 import logging 10 import logging
(...skipping 1359 matching lines...) Expand 10 before | Expand all | Expand 10 after
1370 } 1370 }
1371 self.assertEqual(expected, response.json) 1371 self.assertEqual(expected, response.json)
1372 1372
1373 1373
1374 class BotsApiTest(BaseTest): 1374 class BotsApiTest(BaseTest):
1375 api_service_cls = handlers_endpoints.SwarmingBotsService 1375 api_service_cls = handlers_endpoints.SwarmingBotsService
1376 1376
1377 def test_list_ok(self): 1377 def test_list_ok(self):
1378 """Asserts that BotInfo is returned for the appropriate set of bots.""" 1378 """Asserts that BotInfo is returned for the appropriate set of bots."""
1379 self.set_as_privileged_user() 1379 self.set_as_privileged_user()
1380 then = datetime.datetime(2009, 1, 2, 3, 4, 5, 6)
1381 then_str = unicode(then.strftime(self.DATETIME_FORMAT))
1382 self.mock_now(then)
1383 # Add three bot events, corresponding to one dead bot, one quarantined bot,
1384 # and one good bot
1385 bot_management.bot_event(
1386 event_type='bot_connected', bot_id='id3',
1387 external_ip='8.8.4.4', authenticated_as='bot:whitelisted-ip',
1388 dimensions={'foo': ['bar'], 'id': ['id3']}, state={'ram': 65},
1389 version='123456789', quarantined=False, task_id=None, task_name=None)
1380 now = datetime.datetime(2010, 1, 2, 3, 4, 5, 6) 1390 now = datetime.datetime(2010, 1, 2, 3, 4, 5, 6)
1381 now_str = unicode(now.strftime(self.DATETIME_FORMAT)) 1391 now_str = unicode(now.strftime(self.DATETIME_FORMAT))
1382 self.mock_now(now) 1392 self.mock_now(now)
1383 bot_management.bot_event( 1393 bot_management.bot_event(
1384 event_type='bot_connected', bot_id='id1', 1394 event_type='bot_connected', bot_id='id1',
1385 external_ip='8.8.4.4', authenticated_as='bot:whitelisted-ip', 1395 external_ip='8.8.4.4', authenticated_as='bot:whitelisted-ip',
1386 dimensions={'foo': ['bar'], 'id': ['id1']}, state={'ram': 65}, 1396 dimensions={'foo': ['bar'], 'id': ['id1']}, state={'ram': 65},
1387 version='123456789', quarantined=False, task_id=None, task_name=None) 1397 version='123456789', quarantined=False, task_id=None, task_name=None)
1398 bot_management.bot_event(
1399 event_type='bot_connected', bot_id='id2',
1400 external_ip='8.8.4.4', authenticated_as='bot:whitelisted-ip',
1401 dimensions={'foo': ['bar'], 'id': ['id2']}, state={'ram': 65},
1402 version='123456789', quarantined=True, task_id=None, task_name=None)
1403 bot1 = {
1404 u'authenticated_as': u'bot:whitelisted-ip',
1405 u'bot_id': u'id1',
1406 u'dimensions': [
1407 {u'key': u'foo', u'value': [u'bar']},
1408 {u'key': u'id', u'value': [u'id1']},
1409 ],
1410 u'external_ip': u'8.8.4.4',
1411 u'first_seen_ts': now_str,
1412 u'is_dead': False,
1413 u'last_seen_ts': now_str,
1414 u'quarantined': False,
1415 u'state': u'{"ram":65}',
1416 u'version': u'123456789',
1417 }
1418 bot2 = {
1419 u'authenticated_as': u'bot:whitelisted-ip',
1420 u'bot_id': u'id2',
1421 u'dimensions': [
1422 {u'key': u'foo', u'value': [u'bar']},
1423 {u'key': u'id', u'value': [u'id2']},
1424 ],
1425 u'external_ip': u'8.8.4.4',
1426 u'first_seen_ts': now_str,
1427 u'is_dead': False,
1428 u'last_seen_ts': now_str,
1429 u'quarantined': True,
1430 u'state': u'{"ram":65}',
1431 u'version': u'123456789',
1432 }
1433 bot3 = {
1434 u'authenticated_as': u'bot:whitelisted-ip',
1435 u'bot_id': u'id3',
1436 u'dimensions': [
1437 {u'key': u'foo', u'value': [u'bar']},
1438 {u'key': u'id', u'value': [u'id3']},
1439 ],
1440 u'external_ip': u'8.8.4.4',
1441 u'first_seen_ts': then_str,
1442 u'is_dead': True,
1443 u'last_seen_ts': then_str,
1444 u'quarantined': False,
1445 u'state': u'{"ram":65}',
1446 u'version': u'123456789',
1447 }
1388 expected = { 1448 expected = {
1389 u'items': [ 1449 u'items': [bot1, bot2, bot3],
1390 {
1391 u'authenticated_as': u'bot:whitelisted-ip',
1392 u'bot_id': u'id1',
1393 u'dimensions': [
1394 {u'key': u'foo', u'value': [u'bar']},
1395 {u'key': u'id', u'value': [u'id1']},
1396 ],
1397 u'external_ip': u'8.8.4.4',
1398 u'first_seen_ts': now_str,
1399 u'is_dead': False,
1400 u'last_seen_ts': now_str,
1401 u'quarantined': False,
1402 u'state': u'{"ram":65}',
1403 u'version': u'123456789',
1404 },
1405 ],
1406 u'death_timeout': unicode(config.settings().bot_death_timeout_secs), 1450 u'death_timeout': unicode(config.settings().bot_death_timeout_secs),
1407 u'now': unicode(now.strftime(self.DATETIME_FORMAT)), 1451 u'now': unicode(now.strftime(self.DATETIME_FORMAT)),
1408 } 1452 }
1453 # All bots should be returned with no params
1409 request = swarming_rpcs.BotsRequest() 1454 request = swarming_rpcs.BotsRequest()
1410 response = self.call_api('list', body=message_to_dict(request)) 1455 response = self.call_api('list', body=message_to_dict(request))
1411 self.assertEqual(expected, response.json) 1456 self.assertEqual(expected, response.json)
1412 1457 # All bots should be returned if we don't care about quarantined
1458 request = swarming_rpcs.BotsRequest(
1459 quarantined=swarming_rpcs.ThreeStateBool.NONE)
1460 response = self.call_api('list', body=message_to_dict(request))
1461 self.assertEqual(expected, response.json)
1462 # All bots should be returned if we don't care about is_dead
1463 request = swarming_rpcs.BotsRequest(
1464 is_dead=swarming_rpcs.ThreeStateBool.NONE)
1465 response = self.call_api('list', body=message_to_dict(request))
1466 self.assertEqual(expected, response.json)
1467 # Only bot1 corresponds to these two dimensions
1468 expected[u'items']=[bot1]
1413 request = swarming_rpcs.BotsRequest(dimensions=['foo:bar', 'id:id1']) 1469 request = swarming_rpcs.BotsRequest(dimensions=['foo:bar', 'id:id1'])
1414 response = self.call_api('list', body=message_to_dict(request)) 1470 response = self.call_api('list', body=message_to_dict(request))
1415 self.assertEqual(expected, response.json) 1471 self.assertEqual(expected, response.json)
1416 1472 # Only bot1 corresponds to being not dead and not quarantined and
1473 # this dimension
1474 request = swarming_rpcs.BotsRequest(
1475 dimensions=['foo:bar'],
1476 quarantined=swarming_rpcs.ThreeStateBool.FALSE,
1477 is_dead=swarming_rpcs.ThreeStateBool.FALSE)
1478 response = self.call_api('list', body=message_to_dict(request))
1479 self.assertEqual(expected, response.json)
1480 # exclude bot2 only, which is quarantined
1481 expected[u'items']=[bot1, bot3]
1482 request = swarming_rpcs.BotsRequest(
1483 quarantined=swarming_rpcs.ThreeStateBool.FALSE)
1484 response = self.call_api('list', body=message_to_dict(request))
1485 self.assertEqual(expected, response.json)
1486 # exclude bot3 only, which is dead
1487 expected[u'items']=[bot1, bot2]
1488 request = swarming_rpcs.BotsRequest(
1489 is_dead=swarming_rpcs.ThreeStateBool.FALSE)
1490 response = self.call_api('list', body=message_to_dict(request))
1491 self.assertEqual(expected, response.json)
1492 # only bot2 is quarantined
1493 expected[u'items']=[bot2]
1494 request = swarming_rpcs.BotsRequest(
1495 quarantined=swarming_rpcs.ThreeStateBool.TRUE)
1496 response = self.call_api('list', body=message_to_dict(request))
1497 self.assertEqual(expected, response.json)
1498 # quarantined:true can be paired with other dimensions and still work
1499 request = swarming_rpcs.BotsRequest(
1500 quarantined=swarming_rpcs.ThreeStateBool.TRUE, dimensions=['foo:bar'])
1501 response = self.call_api('list', body=message_to_dict(request))
1502 self.assertEqual(expected, response.json)
1503 # only bot3 is dead
1504 expected[u'items']=[bot3]
1505 request = swarming_rpcs.BotsRequest(
1506 is_dead=swarming_rpcs.ThreeStateBool.TRUE)
1507 response = self.call_api('list', body=message_to_dict(request))
1508 self.assertEqual(expected, response.json)
1509 # is_dead:true can be paired with other dimensions and still work
1510 request = swarming_rpcs.BotsRequest(
1511 is_dead=swarming_rpcs.ThreeStateBool.TRUE, dimensions=['foo:bar'])
1512 response = self.call_api('list', body=message_to_dict(request))
1513 self.assertEqual(expected, response.json)
1514 # not:existing is a dimension that doesn't exist, nothing returned.
1417 request = swarming_rpcs.BotsRequest(dimensions=['not:existing']) 1515 request = swarming_rpcs.BotsRequest(dimensions=['not:existing'])
1418 response = self.call_api('list', body=message_to_dict(request)) 1516 response = self.call_api('list', body=message_to_dict(request))
1419 del expected[u'items'] 1517 del expected[u'items']
1420 self.assertEqual(expected, response.json) 1518 self.assertEqual(expected, response.json)
1421 1519 # quarantined:true can be paired with other non-existing dimensions and
1520 # still work
1521 request = swarming_rpcs.BotsRequest(
1522 quarantined=swarming_rpcs.ThreeStateBool.TRUE, dimensions=['not:exist'])
1523 response = self.call_api('list', body=message_to_dict(request))
1524 self.assertEqual(expected, response.json)
1525 # is_dead:true can be paired with other non-existing dimensions and
1526 # still work
1527 request = swarming_rpcs.BotsRequest(
1528 is_dead=swarming_rpcs.ThreeStateBool.TRUE, dimensions=['not:exist'])
1529 response = self.call_api('list', body=message_to_dict(request))
1530 self.assertEqual(expected, response.json)
1531 # No bot is both dead and quarantined
1532 request = swarming_rpcs.BotsRequest(
1533 is_dead=swarming_rpcs.ThreeStateBool.TRUE,
1534 quarantined=swarming_rpcs.ThreeStateBool.TRUE)
1535 response = self.call_api('list', body=message_to_dict(request))
1536 self.assertEqual(expected, response.json)
1537 # A bad request returns 400
1422 request = swarming_rpcs.BotsRequest(dimensions=['bad']) 1538 request = swarming_rpcs.BotsRequest(dimensions=['bad'])
1423 self.call_api('list', body=message_to_dict(request), status=400) 1539 self.call_api('list', body=message_to_dict(request), status=400)
1424 1540
1425 def test_count_ok(self): 1541 def test_count_ok(self):
1426 """Asserts that BotsCount is returned for the appropriate set of bots.""" 1542 """Asserts that BotsCount is returned for the appropriate set of bots."""
1427 self.set_as_privileged_user() 1543 self.set_as_privileged_user()
1428 self.mock_now(datetime.datetime(2009, 1, 2, 3, 4, 5, 6)) 1544 self.mock_now(datetime.datetime(2009, 1, 2, 3, 4, 5, 6))
1429 bot_management.bot_event( 1545 bot_management.bot_event(
1430 event_type='bot_connected', bot_id='id3', 1546 event_type='bot_connected', bot_id='id3',
1431 external_ip='8.8.4.4', authenticated_as='bot:whitelisted-ip', 1547 external_ip='8.8.4.4', authenticated_as='bot:whitelisted-ip',
1432 dimensions={'foo': ['bar'], 'id': ['id3']}, state={'ram': 65}, 1548 dimensions={'foo': ['bar'], 'id': ['id3']}, state={'ram': 65},
1433 version='123456789', quarantined=True, task_id=None, task_name=None) 1549 version='123456789', quarantined=True, task_id=None, task_name=None)
1434 now = datetime.datetime(2010, 1, 2, 3, 4, 5, 6) 1550 now = datetime.datetime(2010, 1, 2, 3, 4, 5, 6)
1435 self.mock_now(now) 1551 self.mock_now(now)
1436 bot_management.bot_event( 1552 bot_management.bot_event(
1437 event_type='bot_connected', bot_id='id1', 1553 event_type='bot_connected', bot_id='id1',
1438 external_ip='8.8.4.4', authenticated_as='bot:whitelisted-ip', 1554 external_ip='8.8.4.4', authenticated_as='bot:whitelisted-ip',
1439 dimensions={'foo': ['bar'], 'id': ['id1']}, state={'ram': 65}, 1555 dimensions={'foo': ['bar'], 'id': ['id1']}, state={'ram': 65},
1440 version='123456789', quarantined=False, task_id=None, task_name=None) 1556 version='123456789', quarantined=False, task_id='987', task_name=None)
1441 bot_management.bot_event( 1557 bot_management.bot_event(
1442 event_type='bot_connected', bot_id='id2', 1558 event_type='bot_connected', bot_id='id2',
1443 external_ip='8.8.4.4', authenticated_as='bot:whitelisted-ip', 1559 external_ip='8.8.4.4', authenticated_as='bot:whitelisted-ip',
1444 dimensions={'foo': ['bar'], 'id': ['id2']}, state={'ram': 65}, 1560 dimensions={'foo': ['bar'], 'id': ['id2']}, state={'ram': 65},
1445 version='123456789', quarantined=True, task_id='987', task_name=None) 1561 version='123456789', quarantined=True, task_id=None, task_name=None)
1446 expected = { 1562 expected = {
1447 u'count': u'3', 1563 u'count': u'3',
1448 u'quarantined': u'2', 1564 u'quarantined': u'2',
1449 u'dead': u'1', 1565 u'dead': u'1',
1450 u'busy': u'1', 1566 u'busy': u'1',
1451 u'now': unicode(now.strftime(self.DATETIME_FORMAT)), 1567 u'now': unicode(now.strftime(self.DATETIME_FORMAT)),
1452 } 1568 }
1453 request = swarming_rpcs.BotsRequest() 1569 request = swarming_rpcs.BotsRequest()
1454 response = self.call_api('count', body=message_to_dict(request)) 1570 response = self.call_api('count', body=message_to_dict(request))
1455 self.assertEqual(expected, response.json) 1571 self.assertEqual(expected, response.json)
1456 1572
1457 expected = { 1573 expected = {
1458 u'count': u'1', 1574 u'count': u'1',
1459 u'quarantined': u'0', 1575 u'quarantined': u'0',
1460 u'dead': u'0', 1576 u'dead': u'0',
1461 u'busy': u'0', 1577 u'busy': u'1',
1462 u'now': unicode(now.strftime(self.DATETIME_FORMAT)), 1578 u'now': unicode(now.strftime(self.DATETIME_FORMAT)),
1463 } 1579 }
1464 request = swarming_rpcs.BotsRequest(dimensions=['foo:bar', 'id:id1']) 1580 request = swarming_rpcs.BotsRequest(dimensions=['foo:bar', 'id:id1'])
1465 response = self.call_api('count', body=message_to_dict(request)) 1581 response = self.call_api('count', body=message_to_dict(request))
1466 self.assertEqual(expected, response.json) 1582 self.assertEqual(expected, response.json)
1467 1583
1584 request = swarming_rpcs.BotsRequest(
1585 quarantined=swarming_rpcs.ThreeStateBool.FALSE,
1586 is_dead=swarming_rpcs.ThreeStateBool.FALSE)
1587 response = self.call_api('count', body=message_to_dict(request))
1588 self.assertEqual(expected, response.json)
1589
1590
1468 expected[u'quarantined'] = u'1' 1591 expected[u'quarantined'] = u'1'
1469 expected[u'busy'] = u'1' 1592 expected[u'busy'] = u'0'
1470 request = swarming_rpcs.BotsRequest(dimensions=['foo:bar', 'id:id2']) 1593 request = swarming_rpcs.BotsRequest(dimensions=['foo:bar', 'id:id2'])
1471 response = self.call_api('count', body=message_to_dict(request)) 1594 response = self.call_api('count', body=message_to_dict(request))
1472 self.assertEqual(expected, response.json) 1595 self.assertEqual(expected, response.json)
1473 1596
1597 request = swarming_rpcs.BotsRequest(
1598 quarantined=swarming_rpcs.ThreeStateBool.TRUE,
1599 dimensions=['foo:bar', 'id:id2'])
1600 response = self.call_api('count', body=message_to_dict(request))
1601 self.assertEqual(expected, response.json)
1602
1474 expected[u'dead'] = u'1' 1603 expected[u'dead'] = u'1'
1475 expected[u'busy'] = u'0'
1476 request = swarming_rpcs.BotsRequest(dimensions=['foo:bar', 'id:id3']) 1604 request = swarming_rpcs.BotsRequest(dimensions=['foo:bar', 'id:id3'])
1477 response = self.call_api('count', body=message_to_dict(request)) 1605 response = self.call_api('count', body=message_to_dict(request))
1478 self.assertEqual(expected, response.json) 1606 self.assertEqual(expected, response.json)
1479 1607
1608 expected[u'quarantined'] = u'1'
1609 request = swarming_rpcs.BotsRequest(
1610 is_dead=swarming_rpcs.ThreeStateBool.TRUE,
1611 dimensions=['foo:bar', 'id:id3'])
1612 response = self.call_api('count', body=message_to_dict(request))
1613 self.assertEqual(expected, response.json)
1614
1615 request = swarming_rpcs.BotsRequest(
1616 quarantined=swarming_rpcs.ThreeStateBool.TRUE,
1617 is_dead=swarming_rpcs.ThreeStateBool.TRUE,
1618 dimensions=['foo:bar', 'id:id3'])
1619 response = self.call_api('count', body=message_to_dict(request))
1620 self.assertEqual(expected, response.json)
1621
1622 request = swarming_rpcs.BotsRequest(
1623 quarantined=swarming_rpcs.ThreeStateBool.TRUE,
1624 is_dead=swarming_rpcs.ThreeStateBool.TRUE)
1625 response = self.call_api('count', body=message_to_dict(request))
1626 self.assertEqual(expected, response.json)
1627
1480 request = swarming_rpcs.BotsRequest(dimensions=['not:existing']) 1628 request = swarming_rpcs.BotsRequest(dimensions=['not:existing'])
1481 response = self.call_api('count', body=message_to_dict(request)) 1629 response = self.call_api('count', body=message_to_dict(request))
1482 expected = { 1630 expected = {
1483 u'count': u'0', 1631 u'count': u'0',
1484 u'quarantined': u'0', 1632 u'quarantined': u'0',
1485 u'dead': u'0', 1633 u'dead': u'0',
1486 u'busy': u'0', 1634 u'busy': u'0',
1487 u'now': unicode(now.strftime(self.DATETIME_FORMAT)), 1635 u'now': unicode(now.strftime(self.DATETIME_FORMAT)),
1488 } 1636 }
1489 self.assertEqual(expected, response.json) 1637 self.assertEqual(expected, response.json)
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
1773 self.assertEqual(expected, response.json) 1921 self.assertEqual(expected, response.json)
1774 1922
1775 1923
1776 if __name__ == '__main__': 1924 if __name__ == '__main__':
1777 if '-v' in sys.argv: 1925 if '-v' in sys.argv:
1778 unittest.TestCase.maxDiff = None 1926 unittest.TestCase.maxDiff = None
1779 logging.basicConfig(level=logging.DEBUG) 1927 logging.basicConfig(level=logging.DEBUG)
1780 else: 1928 else:
1781 logging.basicConfig(level=logging.CRITICAL) 1929 logging.basicConfig(level=logging.CRITICAL)
1782 unittest.main() 1930 unittest.main()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698