 Chromium Code Reviews
 Chromium Code Reviews 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
    
  
    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| OLD | NEW | 
|---|---|
| 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 Loading... | |
| 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 self.maxDiff = None | |
| 
M-A Ruel
2016/08/09 13:57:27
remove before committing, note that calling the te
 
kjlubick
2016/08/09 17:41:32
Done.
 | |
| 1381 then = datetime.datetime(2009, 1, 2, 3, 4, 5, 6) | |
| 1382 then_str = unicode(then.strftime(self.DATETIME_FORMAT)) | |
| 1383 self.mock_now(then) | |
| 1384 # Add three bot events, corresponding to one dead bot, one quarantined bot, | |
| 1385 # and one good bot | |
| 1386 bot_management.bot_event( | |
| 1387 event_type='bot_connected', bot_id='id3', | |
| 1388 external_ip='8.8.4.4', authenticated_as='bot:whitelisted-ip', | |
| 1389 dimensions={'foo': ['bar'], 'id': ['id3']}, state={'ram': 65}, | |
| 1390 version='123456789', quarantined=False, task_id=None, task_name=None) | |
| 1380 now = datetime.datetime(2010, 1, 2, 3, 4, 5, 6) | 1391 now = datetime.datetime(2010, 1, 2, 3, 4, 5, 6) | 
| 1381 now_str = unicode(now.strftime(self.DATETIME_FORMAT)) | 1392 now_str = unicode(now.strftime(self.DATETIME_FORMAT)) | 
| 1382 self.mock_now(now) | 1393 self.mock_now(now) | 
| 1383 bot_management.bot_event( | 1394 bot_management.bot_event( | 
| 1384 event_type='bot_connected', bot_id='id1', | 1395 event_type='bot_connected', bot_id='id1', | 
| 1385 external_ip='8.8.4.4', authenticated_as='bot:whitelisted-ip', | 1396 external_ip='8.8.4.4', authenticated_as='bot:whitelisted-ip', | 
| 1386 dimensions={'foo': ['bar'], 'id': ['id1']}, state={'ram': 65}, | 1397 dimensions={'foo': ['bar'], 'id': ['id1']}, state={'ram': 65}, | 
| 1387 version='123456789', quarantined=False, task_id=None, task_name=None) | 1398 version='123456789', quarantined=False, task_id=None, task_name=None) | 
| 1399 bot_management.bot_event( | |
| 1400 event_type='bot_connected', bot_id='id2', | |
| 1401 external_ip='8.8.4.4', authenticated_as='bot:whitelisted-ip', | |
| 1402 dimensions={'foo': ['bar'], 'id': ['id2']}, state={'ram': 65}, | |
| 1403 version='123456789', quarantined=True, task_id=None, task_name=None) | |
| 1404 bot1 = { | |
| 1405 u'authenticated_as': u'bot:whitelisted-ip', | |
| 1406 u'bot_id': u'id1', | |
| 1407 u'dimensions': [ | |
| 1408 {u'key': u'foo', u'value': [u'bar']}, | |
| 1409 {u'key': u'id', u'value': [u'id1']}, | |
| 1410 ], | |
| 1411 u'external_ip': u'8.8.4.4', | |
| 1412 u'first_seen_ts': now_str, | |
| 1413 u'is_dead': False, | |
| 1414 u'last_seen_ts': now_str, | |
| 1415 u'quarantined': False, | |
| 1416 u'state': u'{"ram":65}', | |
| 1417 u'version': u'123456789', | |
| 1418 } | |
| 1419 bot2 = { | |
| 1420 u'authenticated_as': u'bot:whitelisted-ip', | |
| 1421 u'bot_id': u'id2', | |
| 1422 u'dimensions': [ | |
| 1423 {u'key': u'foo', u'value': [u'bar']}, | |
| 1424 {u'key': u'id', u'value': [u'id2']}, | |
| 1425 ], | |
| 1426 u'external_ip': u'8.8.4.4', | |
| 1427 u'first_seen_ts': now_str, | |
| 1428 u'is_dead': False, | |
| 1429 u'last_seen_ts': now_str, | |
| 1430 u'quarantined': True, | |
| 1431 u'state': u'{"ram":65}', | |
| 1432 u'version': u'123456789', | |
| 1433 } | |
| 1434 bot3 = { | |
| 1435 u'authenticated_as': u'bot:whitelisted-ip', | |
| 1436 u'bot_id': u'id3', | |
| 1437 u'dimensions': [ | |
| 1438 {u'key': u'foo', u'value': [u'bar']}, | |
| 1439 {u'key': u'id', u'value': [u'id3']}, | |
| 1440 ], | |
| 1441 u'external_ip': u'8.8.4.4', | |
| 1442 u'first_seen_ts': then_str, | |
| 1443 u'is_dead': True, | |
| 1444 u'last_seen_ts': then_str, | |
| 1445 u'quarantined': False, | |
| 1446 u'state': u'{"ram":65}', | |
| 1447 u'version': u'123456789', | |
| 1448 } | |
| 1388 expected = { | 1449 expected = { | 
| 1389 u'items': [ | 1450 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), | 1451 u'death_timeout': unicode(config.settings().bot_death_timeout_secs), | 
| 1407 u'now': unicode(now.strftime(self.DATETIME_FORMAT)), | 1452 u'now': unicode(now.strftime(self.DATETIME_FORMAT)), | 
| 1408 } | 1453 } | 
| 1454 # All bots should be returned with no params | |
| 1409 request = swarming_rpcs.BotsRequest() | 1455 request = swarming_rpcs.BotsRequest() | 
| 1410 response = self.call_api('list', body=message_to_dict(request)) | 1456 response = self.call_api('list', body=message_to_dict(request)) | 
| 1411 self.assertEqual(expected, response.json) | 1457 self.assertEqual(expected, response.json) | 
| 1412 | 1458 # All bots should be returned if we don't care about quarantined | 
| 1459 request = swarming_rpcs.BotsRequest( | |
| 1460 quarantined=swarming_rpcs.ThreeStateBool.NONE) | |
| 1461 response = self.call_api('list', body=message_to_dict(request)) | |
| 1462 self.assertEqual(expected, response.json) | |
| 1463 # All bots should be returned if we don't care about is_dead | |
| 1464 request = swarming_rpcs.BotsRequest( | |
| 1465 is_dead=swarming_rpcs.ThreeStateBool.NONE) | |
| 1466 response = self.call_api('list', body=message_to_dict(request)) | |
| 1467 self.assertEqual(expected, response.json) | |
| 1468 # Only bot1 corresponds to these two dimensions | |
| 1469 expected[u'items']=[bot1] | |
| 1413 request = swarming_rpcs.BotsRequest(dimensions=['foo:bar', 'id:id1']) | 1470 request = swarming_rpcs.BotsRequest(dimensions=['foo:bar', 'id:id1']) | 
| 1414 response = self.call_api('list', body=message_to_dict(request)) | 1471 response = self.call_api('list', body=message_to_dict(request)) | 
| 1415 self.assertEqual(expected, response.json) | 1472 self.assertEqual(expected, response.json) | 
| 1416 | 1473 # exclude bot2 only, which is quarantined | 
| 1474 expected[u'items']=[bot1, bot3] | |
| 1475 request = swarming_rpcs.BotsRequest( | |
| 1476 quarantined=swarming_rpcs.ThreeStateBool.FALSE) | |
| 1477 response = self.call_api('list', body=message_to_dict(request)) | |
| 1478 self.assertEqual(expected, response.json) | |
| 1479 # exclude bot3 only, which is dead | |
| 1480 expected[u'items']=[bot1, bot2] | |
| 1481 request = swarming_rpcs.BotsRequest( | |
| 1482 is_dead=swarming_rpcs.ThreeStateBool.FALSE) | |
| 1483 response = self.call_api('list', body=message_to_dict(request)) | |
| 1484 self.assertEqual(expected, response.json) | |
| 1485 # only bot2 is quarantined | |
| 1486 expected[u'items']=[bot2] | |
| 1487 request = swarming_rpcs.BotsRequest( | |
| 1488 quarantined=swarming_rpcs.ThreeStateBool.TRUE) | |
| 1489 response = self.call_api('list', body=message_to_dict(request)) | |
| 1490 self.assertEqual(expected, response.json) | |
| 1491 # quarantined:true can be paired with other dimensions and still work | |
| 1492 request = swarming_rpcs.BotsRequest( | |
| 1493 quarantined=swarming_rpcs.ThreeStateBool.TRUE, dimensions=['foo:bar']) | |
| 1494 response = self.call_api('list', body=message_to_dict(request)) | |
| 1495 self.assertEqual(expected, response.json) | |
| 1496 # only bot3 is dead | |
| 1497 expected[u'items']=[bot3] | |
| 1498 request = swarming_rpcs.BotsRequest( | |
| 1499 is_dead=swarming_rpcs.ThreeStateBool.TRUE) | |
| 1500 response = self.call_api('list', body=message_to_dict(request)) | |
| 1501 self.assertEqual(expected, response.json) | |
| 1502 # is_dead:true can be paired with other dimensions and still work | |
| 1503 request = swarming_rpcs.BotsRequest( | |
| 1504 is_dead=swarming_rpcs.ThreeStateBool.TRUE, dimensions=['foo:bar']) | |
| 1505 response = self.call_api('list', body=message_to_dict(request)) | |
| 1506 self.assertEqual(expected, response.json) | |
| 1507 # not:existing is a dimension that doesn't exist, nothing returned. | |
| 1417 request = swarming_rpcs.BotsRequest(dimensions=['not:existing']) | 1508 request = swarming_rpcs.BotsRequest(dimensions=['not:existing']) | 
| 1418 response = self.call_api('list', body=message_to_dict(request)) | 1509 response = self.call_api('list', body=message_to_dict(request)) | 
| 1419 del expected[u'items'] | 1510 del expected[u'items'] | 
| 1420 self.assertEqual(expected, response.json) | 1511 self.assertEqual(expected, response.json) | 
| 1421 | 1512 # quarantined:true can be paired with other non-existing dimensions and | 
| 1513 # still work | |
| 1514 request = swarming_rpcs.BotsRequest( | |
| 1515 quarantined=swarming_rpcs.ThreeStateBool.TRUE, dimensions=['not:exist']) | |
| 1516 response = self.call_api('list', body=message_to_dict(request)) | |
| 1517 self.assertEqual(expected, response.json) | |
| 1518 # is_dead:true can be paired with other non-existing dimensions and | |
| 1519 # still work | |
| 1520 request = swarming_rpcs.BotsRequest( | |
| 1521 is_dead=swarming_rpcs.ThreeStateBool.TRUE, dimensions=['not:exist']) | |
| 1522 response = self.call_api('list', body=message_to_dict(request)) | |
| 1523 self.assertEqual(expected, response.json) | |
| 1524 # No bot is both dead and quarantined | |
| 1525 request = swarming_rpcs.BotsRequest( | |
| 1526 is_dead=swarming_rpcs.ThreeStateBool.TRUE, | |
| 1527 quarantined=swarming_rpcs.ThreeStateBool.TRUE) | |
| 1528 response = self.call_api('list', body=message_to_dict(request)) | |
| 1529 self.assertEqual(expected, response.json) | |
| 1530 # A bad request returns 400 | |
| 1422 request = swarming_rpcs.BotsRequest(dimensions=['bad']) | 1531 request = swarming_rpcs.BotsRequest(dimensions=['bad']) | 
| 1423 self.call_api('list', body=message_to_dict(request), status=400) | 1532 self.call_api('list', body=message_to_dict(request), status=400) | 
| 1424 | 1533 | 
| 1425 def test_count_ok(self): | 1534 def test_count_ok(self): | 
| 1426 """Asserts that BotsCount is returned for the appropriate set of bots.""" | 1535 """Asserts that BotsCount is returned for the appropriate set of bots.""" | 
| 1427 self.set_as_privileged_user() | 1536 self.set_as_privileged_user() | 
| 1428 self.mock_now(datetime.datetime(2009, 1, 2, 3, 4, 5, 6)) | 1537 self.mock_now(datetime.datetime(2009, 1, 2, 3, 4, 5, 6)) | 
| 1429 bot_management.bot_event( | 1538 bot_management.bot_event( | 
| 1430 event_type='bot_connected', bot_id='id3', | 1539 event_type='bot_connected', bot_id='id3', | 
| 1431 external_ip='8.8.4.4', authenticated_as='bot:whitelisted-ip', | 1540 external_ip='8.8.4.4', authenticated_as='bot:whitelisted-ip', | 
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1464 request = swarming_rpcs.BotsRequest(dimensions=['foo:bar', 'id:id1']) | 1573 request = swarming_rpcs.BotsRequest(dimensions=['foo:bar', 'id:id1']) | 
| 1465 response = self.call_api('count', body=message_to_dict(request)) | 1574 response = self.call_api('count', body=message_to_dict(request)) | 
| 1466 self.assertEqual(expected, response.json) | 1575 self.assertEqual(expected, response.json) | 
| 1467 | 1576 | 
| 1468 expected[u'quarantined'] = u'1' | 1577 expected[u'quarantined'] = u'1' | 
| 1469 expected[u'busy'] = u'1' | 1578 expected[u'busy'] = u'1' | 
| 1470 request = swarming_rpcs.BotsRequest(dimensions=['foo:bar', 'id:id2']) | 1579 request = swarming_rpcs.BotsRequest(dimensions=['foo:bar', 'id:id2']) | 
| 1471 response = self.call_api('count', body=message_to_dict(request)) | 1580 response = self.call_api('count', body=message_to_dict(request)) | 
| 1472 self.assertEqual(expected, response.json) | 1581 self.assertEqual(expected, response.json) | 
| 1473 | 1582 | 
| 1583 request = swarming_rpcs.BotsRequest( | |
| 1584 quarantined=swarming_rpcs.ThreeStateBool.TRUE, | |
| 1585 dimensions=['foo:bar', 'id:id2']) | |
| 1586 response = self.call_api('count', body=message_to_dict(request)) | |
| 1587 self.assertEqual(expected, response.json) | |
| 1588 | |
| 1474 expected[u'dead'] = u'1' | 1589 expected[u'dead'] = u'1' | 
| 1475 expected[u'busy'] = u'0' | 1590 expected[u'busy'] = u'0' | 
| 1476 request = swarming_rpcs.BotsRequest(dimensions=['foo:bar', 'id:id3']) | 1591 request = swarming_rpcs.BotsRequest(dimensions=['foo:bar', 'id:id3']) | 
| 1477 response = self.call_api('count', body=message_to_dict(request)) | 1592 response = self.call_api('count', body=message_to_dict(request)) | 
| 1478 self.assertEqual(expected, response.json) | 1593 self.assertEqual(expected, response.json) | 
| 1479 | 1594 | 
| 1595 request = swarming_rpcs.BotsRequest( | |
| 1596 is_dead=swarming_rpcs.ThreeStateBool.TRUE, | |
| 1597 dimensions=['foo:bar', 'id:id3']) | |
| 1598 response = self.call_api('count', body=message_to_dict(request)) | |
| 1599 self.assertEqual(expected, response.json) | |
| 1600 | |
| 1601 request = swarming_rpcs.BotsRequest( | |
| 1602 quarantined=swarming_rpcs.ThreeStateBool.TRUE, | |
| 1603 is_dead=swarming_rpcs.ThreeStateBool.TRUE, | |
| 1604 dimensions=['foo:bar', 'id:id3']) | |
| 1605 response = self.call_api('count', body=message_to_dict(request)) | |
| 1606 self.assertEqual(expected, response.json) | |
| 1607 | |
| 1608 request = swarming_rpcs.BotsRequest( | |
| 1609 quarantined=swarming_rpcs.ThreeStateBool.TRUE, | |
| 1610 is_dead=swarming_rpcs.ThreeStateBool.TRUE) | |
| 1611 response = self.call_api('count', body=message_to_dict(request)) | |
| 1612 self.assertEqual(expected, response.json) | |
| 1613 | |
| 1480 request = swarming_rpcs.BotsRequest(dimensions=['not:existing']) | 1614 request = swarming_rpcs.BotsRequest(dimensions=['not:existing']) | 
| 1481 response = self.call_api('count', body=message_to_dict(request)) | 1615 response = self.call_api('count', body=message_to_dict(request)) | 
| 1482 expected = { | 1616 expected = { | 
| 1483 u'count': u'0', | 1617 u'count': u'0', | 
| 1484 u'quarantined': u'0', | 1618 u'quarantined': u'0', | 
| 1485 u'dead': u'0', | 1619 u'dead': u'0', | 
| 1486 u'busy': u'0', | 1620 u'busy': u'0', | 
| 1487 u'now': unicode(now.strftime(self.DATETIME_FORMAT)), | 1621 u'now': unicode(now.strftime(self.DATETIME_FORMAT)), | 
| 1488 } | 1622 } | 
| 1489 self.assertEqual(expected, response.json) | 1623 self.assertEqual(expected, response.json) | 
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1773 self.assertEqual(expected, response.json) | 1907 self.assertEqual(expected, response.json) | 
| 1774 | 1908 | 
| 1775 | 1909 | 
| 1776 if __name__ == '__main__': | 1910 if __name__ == '__main__': | 
| 1777 if '-v' in sys.argv: | 1911 if '-v' in sys.argv: | 
| 1778 unittest.TestCase.maxDiff = None | 1912 unittest.TestCase.maxDiff = None | 
| 1779 logging.basicConfig(level=logging.DEBUG) | 1913 logging.basicConfig(level=logging.DEBUG) | 
| 1780 else: | 1914 else: | 
| 1781 logging.basicConfig(level=logging.CRITICAL) | 1915 logging.basicConfig(level=logging.CRITICAL) | 
| 1782 unittest.main() | 1916 unittest.main() | 
| OLD | NEW |