| 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     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  Loading... | 
| 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() | 
| OLD | NEW | 
|---|